Cryonel

Fix webhook signature verification failures

Webhook signatures protect authenticity and integrity. Most failures come from hashing different bytes, using the wrong secret or scheme, or parsing a timestamp incorrectly.

Preserve the raw request body

Capture the exact body bytes before JSON, form, or text middleware transforms them. Parsing and re-serializing JSON can change whitespace, property order, escapes, or number formatting even when the data looks equivalent. Configure the framework’s raw-body hook only for the webhook route, then parse the event after verification succeeds.

Follow the provider’s signing scheme exactly

Read how the provider constructs its signed payload. It may sign only the body or combine a timestamp, separator, identifier, method, and path. Parse versioned signature headers without assuming the first value is current. Decode hexadecimal or Base64 at the correct step and use the named HMAC or public-key algorithm. Similar-looking schemes are not interchangeable.

Use the correct endpoint secret

Webhook secrets often differ between test and production endpoints, accounts, or destinations. Confirm the receiving URL and secret belong together without printing the secret. During rotation, accept the documented old and new secrets for a short overlap, then remove the old value. Do not fall back to accepting an unverified event when configuration is missing.

Compare safely and reject replay

Compute the expected signature with the platform cryptography library and use its constant-time comparison for equal-length byte sequences. Check the signed timestamp against a small documented tolerance and store an event identifier when the provider supports replay detection. Clock synchronization matters, but widening the tolerance indefinitely defeats the protection.

Return the right response

Reject invalid signatures before performing business actions and return the provider’s expected failure status. For valid events, make handling idempotent because providers retry on timeouts and transient failures. Acknowledge only after durable acceptance, such as a database transaction or queue write, and keep expensive processing out of the request path.

Debug without leaking secrets

Log a request ID, provider event ID, algorithm version, body byte length, timestamp age, and verification outcome. Never log the raw secret, authorization headers, complete sensitive payload, or expected signature. Compare a provider CLI fixture or signed test event byte-for-byte. Encoding can be inspected locally with the Base64 tool, but Cryonel does not verify provider-specific secrets.

Frequently Asked Questions

Can I verify re-serialized JSON?

Usually no. Verify the required raw bytes first.

Should I use ordinary equality?

Use a constant-time cryptographic comparison.

Why check the timestamp?

It limits replay of captured valid requests.

Related Tools and Guides