Cybersecurity
Webhook Signature Verification: Prevent Forged Events
Verify webhook authenticity with raw-body HMAC signatures, timestamps, replay protection, key rotation, and safe event processing.
In this article
Webhook Signature Verification: Prevent Forged Events
A webhook endpoint is a public URL that receives events from another service. Without verification, anyone who discovers the endpoint may be able to submit a forged payment, deployment, account, or automation event. TLS protects transport, but it does not prove that the request came from the expected sender.
Most providers sign a timestamp and the exact request body using a shared secret or private key. Your endpoint must verify the signature before parsing and acting on the event.
What the problem means
Signature schemes differ, but a common design computes an HMAC over a canonical message containing the timestamp and raw body. The receiver recomputes the value with its secret and compares it in constant time. A timestamp tolerance and event-ID store help prevent replay of a valid captured request.
Core design principles
Verify the raw bytes
JSON parsing and reserialization can change whitespace or key order. Capture the exact request body required by the provider’s specification.
Reject before processing
Do not enqueue, log sensitive content, update state, or return a misleading success until the signature and timestamp pass.
Prevent replay
Reject timestamps outside a reasonable window and deduplicate stable event IDs for longer-lived protection.
Support planned rotation
Allow old and new secrets during a short controlled overlap, record which one verified, and remove the old value promptly.
Step-by-step workflow
- Read the provider contract. Confirm header names, algorithm, signed message format, encoding, version prefix, timestamp units, and retry behavior.
- Capture the raw body. Configure framework middleware so signature verification sees original bytes before JSON parsing modifies representation.
- Parse headers defensively. Bound lengths, reject missing or duplicate critical values, and support only documented signature versions.
- Compute and compare. Use a maintained cryptographic library and constant-time comparison. Do not implement an algorithm from scratch.
- Check time and duplication. Validate timestamp tolerance, normalize units, and store processed event IDs with an appropriate expiry.
- Process idempotently. Return quickly after durable acceptance, handle provider retries, and make event effects safe when the same valid event arrives again.
Practical example
A payment webhook arrives twice because the first response was delayed. Both requests pass signature verification, but the receiver stores the event ID atomically. The first creates the payment update; the second returns success without repeating the effect. A request with an old timestamp is rejected even if its captured signature is valid.
How to test the control
Test this workflow in a controlled environment before relying on it during a real incident. Begin with “Read the provider contract” and create three cases: an expected success, a safe rejection, and a degraded or unavailable dependency. Continue through “Capture the raw body” and “Parse headers defensively,” recording the observed status, timestamps, logs, and operator decision. Repeat the test after a material configuration, provider, dependency, or permission change. A control is operational only when another team member can follow the documented process and obtain the expected result without hidden knowledge.
Metrics and review cadence
Measure both completion and outcome. For this topic, track evidence that “Raw body is available,” “Documented algorithm is used,” and “Comparison is constant-time” remain true, then pair those checks with operational signals such as failures, denied actions, recovery time, unexpected destinations, retry volume, or stale ownership as appropriate. Review trends instead of celebrating a one-time pass. A rising exception count can show that the workflow is too difficult, while zero alerts may mean the detection path is not working.
Operating this in production
The goal of a defensive workflow is to reduce both probability and blast radius. Inventory what can be abused, limit standing privileges, preserve evidence, and rehearse recovery. A short checklist practiced in advance is more valuable than a long document first opened during an incident. Review the workflow after incidents, architecture changes, new integrations, and meaningful traffic growth. Assign an owner and measure whether the control works instead of recording only that it exists.
Common mistakes
- Verifying reserialized JSON instead of raw bytes.
- Comparing signatures with an ordinary equality function.
- Accepting any timestamp.
- Logging the signing secret or full sensitive payload.
- Treating signature verification as authorization for every business action.
Duck Cloud tools for the workflow
Use the JSON Validator and JSON Viewer only after authenticity checks in production. For safe development fixtures, the SHA-256 Generator, Unix Timestamp Converter, and Text Diff can help inspect canonical messages and timing.
Review checklist
- [ ] Raw body is available
- [ ] Documented algorithm is used
- [ ] Comparison is constant-time
- [ ] Timestamp tolerance is enforced
- [ ] Event IDs are deduplicated
- [ ] Processing is idempotent
- [ ] Secrets rotate safely
- [ ] Failed verification is monitored without leaking data
Conclusion
Webhook Signature Verification is most effective when it becomes a repeatable engineering habit. Start with the highest-impact boundary, document the expected behavior, test realistic failure cases, and keep evidence that the control works. Small, verified safeguards compound into a system that is easier to operate and safer to change.