Glossary
HMAC
Hash-based Message Authentication Code — a cryptographic signature that proves a webhook came from a specific sender and wasn't tampered with in transit.
HMAC combines a shared secret and the message body through a hash function (usually SHA-256) to produce a fixed-length signature. The sender computes the signature using the secret + body; the receiver re-computes it using the same secret + body and checks for an exact byte-for-byte match.
If the body changes by a single byte — or if anyone without the secret tries to forge a message — the signature won't match. This is why HMAC is the foundation of webhook security at Stripe, GitHub, Shopify, Slack, and nearly every modern API.
Crucially, the comparison must be timing-safe: a naive === check leaks information about how many leading bytes matched, enabling a side-channel attack. Use crypto.timingSafeEqual (Node) or hmac.compare_digest (Python).
Verify an HMAC-SHA256 signature in Node.js
import { createHmac, timingSafeEqual } from "crypto";
function verify(body: string, signature: string, secret: string) {
const expected = createHmac("sha256", secret).update(body).digest("hex");
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}How HookSense helps
HookSense verifies HMAC signatures for Stripe, GitHub, Shopify, and custom providers automatically — drop in the secret and every captured request shows pass/fail.
Get a free webhook URL