Sendgrid-php: Issue in Signed Event Webhook - PHP

Created on 29 Apr 2021  路  7Comments  路  Source: sendgrid/sendgrid-php

Issue Summary

I have followed the steps given in https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook-security-features/ for PHP and used library mentioned in https://github.com/sendgrid/sendgrid-php/tree/main/lib/eventwebhook similarly checked unittest https://github.com/sendgrid/sendgrid-php/blob/main/test/unit/EventWebhookTest.php for event signature verification

Steps to Reproduce

  1. Went to https://app.sendgrid.com/settings/mail_settings and did test your integration with the ngrok url.
  2. Got request with header on ngrok url
  3. Output from verifySignature is false.

Code Snippet

$timestamp = $req->header("X-Twilio-Email-Event-Webhook-Timestamp");
$signature = $req->header("X-Twilio-Email-Event-Webhook-Signature");
$verifycationKey = "<Verification Key>";
$body = \json_encode($req->all())."\r\n";
\Log::info("+++++++++++++++++++");
\Log::info($body);
\Log::info($timestamp);
\Log::info($signature);

$event = new EventWebhook;

$publicKey = $event->convertPublicKeyToECDSA($verifycationKey);
\Log::info(serialize($publicKey));
$flag =$event->verifySignature($publicKey, $body, $signature, $timestamp);
\Log::info("flag====> ".$flag);
\Log::info("+++++++++++++++++++");

Technical details:

  • sendgrid-php version: 7.9
  • php version: 7.2
bug

Most helpful comment

This replacement worked for me on multi-event payloads instead of the one above:

$bodyContent = str_replace(
    "},\n{", // The raw string comes in with newlines in this spot
    "},\r\n{",
    $body // $request->getContent() can be used here for Laravel apps
)."\r\n";

All 7 comments

We've seen a similar issue in our nodejs library recently: https://github.com/sendgrid/sendgrid-nodejs/issues/1238

Is this a multi-event webhook? If so, a carriage return and newline (rn) needs to be included between every event in the body. Example: https://github.com/sendgrid/sendgrid-nodejs/pull/1271/files#diff-570eee91600a9234a175a0acce452638ee2c7cc583be1a4aa75eb35ca8b9500cR48

Yes we are having multi-event webhook. As per your comment we have modified the code as follows still not luck.

`
$timestamp = $req->header("X-Twilio-Email-Event-Webhook-Timestamp");
$signature = $req->header("X-Twilio-Email-Event-Webhook-Signature");
$verifycationKey = "";
$body = json_encode($req->all());
$body = str_replace("},{", "},rn{",$body)."rn";
Log::info("+++++++++++++++++++");
Log::info($body);
Log::info($timestamp);
Log::info($signature);

$event = new EventWebhook;

$publicKey = $event->convertPublicKeyToECDSA($verifycationKey);
Log::info(serialize($publicKey));
$flag =$event->verifySignature($publicKey, $body, $signature, $timestamp);
Log::info("flag====> ".$flag);
Log::info("+++++++++++++++++++");
`

@iprashant have you tried with the raw body?

$body = $request->getContent()
$body = str_replace("},{", "},\r\n{",$body)."\r\n";

Hi Shwetha,

I have used PHP file_get_contents('php://input'); still no luck.

Thanks,

OK, we have an internal ticket to investigate the multi-event webhook scenario. Marking this as a bug in the meantime.

This issue has been added to our internal backlog to be prioritized. Pull requests and +1s on the issue summary will help it move up the backlog.

This replacement worked for me on multi-event payloads instead of the one above:

$bodyContent = str_replace(
    "},\n{", // The raw string comes in with newlines in this spot
    "},\r\n{",
    $body // $request->getContent() can be used here for Laravel apps
)."\r\n";

Thank you for taking the time to share your solution @peter-at-bpt!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

atsareva picture atsareva  路  4Comments

jverlee picture jverlee  路  4Comments

Theolodewijk picture Theolodewijk  路  4Comments

FilipLukac picture FilipLukac  路  4Comments

Aubynj picture Aubynj  路  3Comments