hygraph / hygraph-utils

1 stars 4 forks source link

Large webhooks fail validation #5

Closed fisherdarling closed 2 years ago

fisherdarling commented 2 years ago

Our webhook validations are failing when we receive models with a large amount of data.

The issue is that verifyWebhookSignature takes in a javascript object which it then serializes into JSON and checks the signature. JSON.stringify is not always deterministic with large payloads which causes the signature to be invalid.

When the payload is small enough, the following is often true. JSON.stringify(JSON.parse(<escaped_payload>)) === <escaped_payload But when the payload is large enough, like ours at 4KB, the above is often false. This leads to a different signing payload and therefore an invalid signature.

To get around this locally, I've re-implemented the signing algorithm and use the raw payload as the Body param. I would like to keep using this library though, so I propose a non-breaking change:

  1. Add a rawPayload parameter to the function.
  2. Replace Body: JSON.stringify(body) with Body: rawPayload || JSON.stringify(body)

That way I can pass in the raw payload and use that for signature verification.

I'm happy to write a PR!

Sidenote

If there is ever a v2 for webhooks / webhook verification, I would recommend using a concatenative approach for signing payloads. Also, a hex digest should be used: .digest('hex')

Something like: <timestamp>|<environment>|<raw_payload>

Here's stripe's docs on manual verification (they use .): https://stripe.com/docs/webhooks/signatures#verify-manually

notrab commented 2 years ago

Hey @fisherdarling id happily merge a PR that covers that.

Thank you so much 🙌

github-actions[bot] commented 2 years ago

:tada: This issue has been resolved in version 1.1.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: