Use Webhook Signatures to verify webhook events are coming from HostedHooks
Each webhook event is sent with a header
HTTP_HOSTEDHOOKS_SIGNATUREcontaining a signature and timestamp. These can be used together with your endpoint secret to compare signatures and confirm that the webhook event you are receiving came from HostedHooks.
Replay attacks are when an attacker intercepts a webhook message and resends it to the endpoint. We help mitigate this by adding a timestamp into the
HTTP_HOSTEDHOOKS_SIGNATUREfor you to compare with. We use this timestamp to sign the payload, so the attacker would not be able to change the timestamp without invalidating the payload signature as well. In the case where the payload signature is valid, but the timestamp is too old, you can choose to reject the webhook.
We generate a new timestamp and signature when webhook messages are sent to the subscriber's endpoint. In the case of retries (where a previous webhook attempt returned a non 200 response), we will generate a new timestamp and signature.
HostedHooks webhook messages will be sent with a
HTTP_HOSTEDHOOKS_SIGNATUREthat contains both a payload signature
s=and a timestamp
New lines have been added here to make it more readable, but the actual
HTTP_HOSTEDHOOKS_SIGNATUREis on one line.
Split the header using the
,to get both the
tvalues. Then use the
=to split the keys from the value. The
svalue corresponds to the payload signature and the
tvalue corresponds to the timestamp.
To create the signed payload you will want to concatenate the following values
- The timestamp
- the character
- The JSON payload received (request body)
Generate an HMAC with the SHA256 hash function. The key for the hash function is your endpoints signing secret and the
signed_payloadstring is the message.
Compare the signature that you received in the header (Step 1) with the generated signature (Step 3). If those match, then calculate the difference between the current timestamp and the received timestamp (step 1) and determine if the difference is within an acceptable tolerance.
Use a constant time string comparison to compare the generated signature with the received signature. This will protect against timing attacks.