Webhook Signatures
Use Webhook Signatures to verify webhook events are coming from HostedHooks
Each webhook event is sent with a header HTTP_HOSTEDHOOKS_SIGNATURE
containing 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.
Prevent Replay Attacks
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_SIGNATURE
for 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 Signature Verification
HostedHooks webhook messages will be sent with a HTTP_HOSTEDHOOKS_SIGNATURE
that contains both a payload signature s=
and a timestamp t=
.
New lines have been added here to make it more readable, but the actual HTTP_HOSTEDHOOKS_SIGNATURE
is on one line.
Step 1: Parse the timestamp and signatures from the header
Split the header using the ,
to get both the s
and t
values. Then use the =
to split the keys from the value. The s
value corresponds to the payload signature and the t
value corresponds to the timestamp.
Step 2: Create the signed_payload
To create the signed payload you will want to concatenate the following values
The timestamp
the character
.
The JSON payload received (request body)
Step 3: Generate the expected Signature
Generate an HMAC with the SHA256 hash function. The key for the hash function is your endpoints signing secret and the signed_payload
string is the message.
Step 4: Compare the signatures
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.
Last updated