Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue in Signed Event Webhook - PHP #1046

Open
iprashant opened this issue Apr 29, 2021 · 9 comments
Open

Issue in Signed Event Webhook - PHP #1046

iprashant opened this issue Apr 29, 2021 · 9 comments
Labels
type: bug bug in the library

Comments

@iprashant
Copy link

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
@eshanholtz
Copy link
Contributor

We've seen a similar issue in our nodejs library recently: sendgrid/sendgrid-nodejs#1238

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

@eshanholtz eshanholtz added status: waiting for feedback waiting for feedback from the submitter type: question question directed at the library labels Apr 30, 2021
@iprashant
Copy link
Author

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("},{", "},\r\n{",$body)."\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("+++++++++++++++++++");
`

@shwetha-manvinkurke
Copy link
Contributor

@iprashant have you tried with the raw body?

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

@iprashant
Copy link
Author

Hi Shwetha,

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

Thanks,

@shwetha-manvinkurke
Copy link
Contributor

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.

@shwetha-manvinkurke shwetha-manvinkurke added type: bug bug in the library and removed status: waiting for feedback waiting for feedback from the submitter type: question question directed at the library labels May 15, 2021
@peter-at-bpt
Copy link

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";

@thinkingserious
Copy link
Contributor

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

@jobveldhuis
Copy link

Hey there, we at fonQ are running into the same issue with the signature verification and the solution of @peter-at-bpt unfortunately does not seem to work. What is the status of your internal investigation?

@shyammsuvarna
Copy link

webhook signed webhook getting false for function = isValidSignature

$publicKey = 'my key';

$input = '[{"DRUPAL_ROOT":"/home/gems2/git/harmony","OURHTTP_HOST":"gemslocal2.artofliving.org","OURREQUEST_URI":"/ca/civicrm/event/register","contact_id":"24495","countryCode":"ca","email":"paul@yopmail.com","event":"processed","newHash":"87858ab1e574e0be","newJobId":"39003277","newQueueId":11312,"newemail_id":"13842","send_at":0,"sg_event_id":"cHJvY2Vzc2VkLTIyOTY4OTQyLWlhcXlDLWhlUW5TRnc4LWtsX0dTOWctMA","sg_message_id":"iaqyC-heQnSFw8-kl_GS9g.filterdrecv-7489454b79-khx4b-1-611E028F-2B.0","smtp-id":"iaqyC-heQnSFw8-kl_GS9g@geopod-ismtpd-6-0","timestamp":1629356687,"uniqueParam":"b.39003277.11312.87858ab1e574e0be@newsletter.india.artofliving.org"},{"DRUPAL_ROOT":"/home/gems2/git/harmony","OURHTTP_HOST":"gemslocal2.artofliving.org","OURREQUEST_URI":"/ca/civicrm/event/register","contact_id":"24495","countryCode":"ca","email":"paul@yopmail.com","event":"delivered","ip":"50.31.63.175","newHash":"87858ab1e574e0be","newJobId":"39003277","newQueueId":11312,"newemail_id":"13842","response":"250 mail saved","sg_event_id":"ZGVsaXZlcmVkLTAtMjI5Njg5NDItaWFxeUMtaGVRblNGdzgta2xfR1M5Zy0w","sg_message_id":"iaqyC-heQnSFw8-kl_GS9g.filterdrecv-7489454b79-khx4b-1-611E028F-2B.0","smtp-id":"iaqyC-heQnSFw8-kl_GS9g@geopod-ismtpd-6-0","timestamp":1629356688,"tls":0,"uniqueParam":"b.39003277.11312.87858ab1e574e0be@newsletter.india.artofliving.org"}]';

$headerStringValue = $_SERVER['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE'];

$timestamp = $_SERVER['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP'];

and i am calling function like below

$result = isValidSignature($publicKey,$input,$headerStringValue,$timestamp);

i am getting result as false- but all values i am passing fine and also php library also fine.

help me to proceed , whats wrong in above code or any other setting i need to enable?

i have tested in postman by passing these details.

when i debugged - i am getting false from this function :

$success = openssl_verify($message, $signature->toDer(), $publicKey->openSslPublicKey, OPENSSL_ALGO_SHA256);

here its false , please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug bug in the library
Projects
None yet
Development

No branches or pull requests

7 participants