How to verify a webhook signature
Verify an incoming webhook with an HMAC signature so you only trust genuine events. Step-by-step with the security pitfalls to avoid.
Verifying a webhook signature ensures the event really came from the provider and was not forged or altered. The standard approach is an HMAC over the raw body with a shared secret — here is how to do it correctly.
Use the raw body
Compute the HMAC over the exact raw request body bytes, before any JSON parsing or re-serialization — even a whitespace change breaks the signature. Grab the raw body in your framework (many parse it by default) and pass it, plus your shared secret, into HMAC-SHA256.
Compare in constant time
Compare your computed signature to the header value using a constant-time comparison (like hmac.compare_digest or crypto.timingSafeEqual), never a plain ==, to avoid leaking match progress through timing. Reject the webhook if they differ, and consider checking a timestamp to prevent replay.
Step by step
Read the signature header the provider sends (e.g. X-Signature).
Compute HMAC-SHA256 over the RAW request body using your shared secret.
Compare your value to the header with a constant-time comparison.
Reject on mismatch; optionally verify a timestamp to block replays.
Try it now — free, no signup
Use the hash generator in your browser. Then, when you need it at scale with an API key and higher limits, grab the full Eveses API.