Verify a webhook against the exact request body the sender signed, using that provider’s documented signing scheme, before parsing the payload or taking action. Preserve the original body bytes, compare signatures with a constant-time or provider SDK check, and handle timestamp freshness and duplicate deliveries separately. Header names, signed inputs, digest encodings, and replay protections differ by provider, so a generic HMAC recipe is not safe to apply everywhere.
What does secure webhook signature verification require?
A signature proves that a request matches a value calculated using a secret and the sender’s prescribed signing input. It does not make arbitrary handling of the request safe: verify first, and only then trust its contents or trigger downstream work. The verifier must receive the same original body bytes the provider used. Parsing JSON and serializing the resulting object again can change whitespace, key order, or encoding and cause verification to fail. GitHub, Shopify, and Stripe all document the importance of verifying the provider-defined payload or unmodified request body (GitHub; Shopify; Stripe).
As an Amazon Associate I earn from qualifying purchases.
- Capture the original body. Do this at the framework boundary, before middleware or application code parses or transforms it.
- Follow the sender’s exact recipe. Use its specified header, secret, signing input, digest algorithm, output encoding, and any prefix or timestamp rules. Prefer its official SDK when one is available.
- Compare securely. Use the SDK’s verification routine or a constant-time comparison function, not ordinary string equality for a secret-derived signature. GitHub and Slack explicitly recommend secure comparison (GitHub; Slack).
- Apply any documented freshness check. A timestamp can limit how long a captured request remains acceptable, but only if the provider’s scheme includes one and your receiver checks it.
- Parse and process only after verification succeeds. Return an appropriate client error for an invalid request; do not continue into business logic.
Keep high-entropy secrets out of source code, logs, and public issue reports. Use the secret belonging to the endpoint that received the delivery; a local forwarding tool may use a different secret from the production endpoint. GitHub recommends a high-entropy secret stored securely, and Stripe identifies using the wrong endpoint secret as a common verification failure (GitHub; Stripe).
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11How do common providers sign webhook requests?
These schemes are not interchangeable. Use the table to identify the pieces to check, then follow the provider’s linked instructions or SDK rather than assembling a cross-provider verifier.
#1 Best Overall
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
| Provider | Header and signing input | Digest, freshness, and delivery handling |
|---|---|---|
| GitHub | X-Hub-Signature-256; HMAC over the payload contents using the configured secret. |
SHA-256 hex digest with the sha256= prefix. The cited guide does not specify a signed timestamp; do not assume its signature provides timestamp-based replay protection. The delivery ID can support deduplication. See GitHub’s validation guide. |
| Shopify | For HTTPS deliveries, X-Shopify-Hmac-SHA256; HMAC-SHA256 over the raw request body using the app client secret. |
Digest is base64-encoded. Shopify says Google Cloud Pub/Sub and Amazon EventBridge deliveries do not require this HMAC verification. For duplicate handling, process idempotently or persist X-Shopify-Webhook-Id. See Shopify’s verification guide. |
| Slack | X-Slack-Request-Timestamp and X-Slack-Signature; sign the exact string v0:<timestamp>:<raw-body> with the signing secret. |
Compare the resulting HMAC-SHA256 hex digest with the header’s v0= value using a secure comparison. Slack’s example rejects timestamps more than five minutes from local time. See Slack’s request verification guide. |
| Stripe | Use the official SDK’s constructEvent() with the original request body, Stripe-Signature header, and the endpoint secret. |
Use the SDK’s verification rather than substituting a generic recipe. Stripe’s guide also covers raw-body retrieval in Express, Next.js, and API Gateway/Lambda. See Stripe’s signature guide. |
| Svix | Webhook-Id, Webhook-Timestamp, and Webhook-Signature; signed content is <id>.<timestamp>.<raw-body>. |
HMAC-SHA256; Svix libraries reject timestamps more than five minutes from current time. The message ID is part of the signed content and can also identify a delivery. See the Svix Django guide. |
Timestamp support is not universal. In Svix’s 2023 survey, 45 of 83 surveyed webhook providers included a timestamp; that is a historical publisher-reported result, not a measurement of today’s provider ecosystem (Svix, State of Webhooks 2023).
How do you preserve the raw body in common frameworks?
Framework examples below show where the raw body belongs in the request flow, not a complete recipe for every version or hosting setup. Middleware order, body APIs, and gateway transformations vary; check the supported SDK and framework documentation for your deployment.
Rank #2
- POWERFUL SECURITY KEY: The YubiKey 5C NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5C NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
Express and Node.js
Mount the provider’s webhook route with raw-body handling before general JSON parsing. Shopify’s manual Express example uses express.raw() and requires verification middleware to run before body parsers. Stripe likewise warns that applying express.json() first mutates the body; place its webhook route before that parser and pass the untouched request body to constructEvent() along with the signature header and endpoint secret (Shopify; Stripe).
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Flask
For Slack, call request.get_data() to obtain the raw request data before accessing methods that deserialize it. Build the exact Slack signing string from the timestamp and raw body, verify the signature securely, and apply Slack’s timestamp check before processing the payload (Slack’s Flask guidance).
Rank #3
- POWERFUL SECURITY KEY: The Security Key NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key NFC via USB-A and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
Django
Svix’s Django example reads request.body and passes the payload and request headers to Webhook(secret).verify(payload, headers). Handle verification failure as a client error and only process the message after successful verification (Svix’s Django guide).
Ruby on Rails
Svix’s Rails example reads request.body and passes the payload and request headers to its verifier before acting on the message (Svix’s Rails guide). GitHub’s Ruby example rewinds and reads the body before JSON parsing, which is important when earlier code has already read from the request stream (GitHub’s validation guide).
Rank #4
- FIDO2 SECURITY KEY: A versatile, tamper-evident USB-C authentication device with sensitive presence detection for online security. FIDO 2.0 level 1 and U2F certified
- PASSWORDLESS CONVENIENCE: Replace frustrating passwords with a simple 4-digit PIN for accessing apps and sites. Seamlessly login to web apps and Windows sessions
- BROAD COMPATIBILITY: Works with Windows, Mac, Linux, Apple, iOS, iPhone, Android and USB-C devices. Seamlessly integrates with Identity Providers or Credential Management Systems supporting FIDO2, including Thales, Microsoft, AWS, and Google
- ENHANCED USER ADOPTION: Features a sensitive presence detector on the USB key, providing ease of use and superior security. Certified for U2F and FIDO2, ideal for individuals who want to secure access to their personal online accounts - Microsoft, Google, Twitter, Facebook, GitHub
- THALES: We offer a wide range of FIDO authenticators, providing robust, phishing-resistant MFA that comply with stringent regulations. With almost three decades of experience, Thales is a pioneer in passwordless authentication devices, supported globally by the FIDO Alliance and industry analysts
Does a valid signature prevent replay or duplicate processing?
No. Signature verification establishes that the request matches the sender’s signing scheme; it does not, by itself, guarantee that the delivery is new or that your business action will happen only once. Where the provider signs a timestamp, reject requests outside its documented tolerance and keep the receiver’s clock synchronized. Slack notes that its signature depends on the timestamp to protect against replay attacks; its example uses a five-minute window (Slack). Svix libraries use a five-minute timestamp window as well (Svix).
Separately, make processing idempotent or deduplicate using a stable delivery or message ID where the provider supplies one. Retries and duplicate deliveries can occur even when a signature is valid. Shopify recommends idempotent processing or storing X-Shopify-Webhook-Id; GitHub’s delivery ID can also support deduplication (Shopify; GitHub). Timestamp rejection and duplicate control solve different problems, so neither should be treated as a substitute for the other.
Why is webhook signature verification failing?
Check these causes in order, without logging the secret or publishing a real payload that may contain sensitive data:
- Wrong secret: Confirm that the secret belongs to the endpoint receiving the delivery. Stripe CLI forwarding and the dashboard endpoint can use different secrets (Stripe).
- Body was parsed or changed: Capture the original bytes before JSON or form parsing. Check whether a proxy, load balancer, or gateway template has transformed the body or relevant headers (GitHub; Stripe).
- Wrong signing recipe: Recheck the exact signed input, hash algorithm, output encoding, header name, version prefix, and secret format against that provider’s documentation. Hex and base64 digests, for example, are not interchangeable.
- Timestamp mismatch: For a timestamped scheme, check the local system clock and the provider’s documented tolerance. Do not apply a shared tolerance to providers whose cited instructions do not specify one (Slack; Svix).
- Parsing happens too early: Confirm that verification runs before payload parsing and business logic. In Express, inspect the order of the webhook route and general JSON parser (Shopify; Stripe).
If all inputs appear correct, compare the framework’s captured raw body and headers with the provider’s delivery details using a safe, non-production test delivery. Avoid placing secrets in logs or issue reports while debugging.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




