Verifying Signatures

Webhooks are an incredibly useful feature that allows your application to react to events as they happen in real time. However, they also open up a potential vector for malicious actors to send fake events to your application. Therefore, it is crucial to verify the authenticity of the events you receive.

At Hook0, we include a signature with each webhook event we send. This signature is a cryptographically secure hash of the payload, created using a secret key that only you and Hook0 know. By comparing the signature included in the event with the one you compute yourself, you can verify the authenticity of the event.

How It Works

  1. When we send a webhook event, we generate a signature. This signature is computed by taking a hash (SHA-256 in our case) of the event payload, using a secret key that only you and Hook0 know.

  2. This signature is included in the headers of the HTTP request we send to your webhook URL. The header key is X-Hook0-Signature.

  3. When you receive a webhook event, before processing it, you should compute the signature on your side. To do this, you need to take a hash of the event payload, using the same secret key.

  4. Then, you compare the signature you computed with the signature included in the headers of the HTTP request. If they match, you can be sure that the event is authentic and was sent by Hook0. If they don't match, you should reject the event.

Verifying Webhook Signatures

Here are the steps to verify webhook signatures:

Step 1: Extract the timestamp and signatures from the header

Firstly, split the X-Hook0-Signature header value using the , character as the separator to get a list of elements. Then split each element using the = character as the separator to get a prefix and value pair.

The t prefix corresponds to the timestamp, and v0 corresponds to the signature. You can ignore all other elements.

Step 2: Prepare the signed_payload string

The signed_payload string is created by concatenating the following:

  • The timestamp (as a string)
  • The character .
  • The actual payload (that is, the request body)

Step 3: Determine the expected signature

Compute a HMAC with the SHA256 hash function. Use the subscription’s signing secret as the key, and the signed_payload string as the message.

Step 4: Compare the signatures

Compare the signature in the header to the signed_payload string. If the signatures match, compute the difference between the current timestamp and the received timestamp. Decide if this difference falls within your acceptable limits.

To safeguard against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures.

Limitations and Considerations

  • The security of this method hinges on the secrecy of the secret key. If a malicious actor gains access to your secret key, they could create valid signatures and send fake events that would pass verification.

  • Supplement with other security measures: Use HTTPS for your webhook URL to secure data transmission.

What’s Next