Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Prevent webhook replay attacks with two layered checks: verify a signature that covers the exact raw request body and timestamp, then reject stale requests and atomically deduplicate each authenticated event or message ID before its business action runs. A signature alone does not stop someone from resending a captured, valid request.
Why a valid webhook signature can still be replayed
A webhook signature helps establish that a request has not been altered and was produced by a party with access to the provider’s signing secret, according to that provider’s scheme. It does not, by itself, prove that the request has not been sent before. An attacker who captures a valid signed request may resend it while your endpoint accepts it.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
XCHTX Anti Theft Security Locking Hooks with a Magnetic Key for Free,6" Pegboard Accessories,Retail... | $64.99 | Buy on Amazon |
As an Amazon Associate I earn from qualifying purchases.
Timestamp validation and idempotency address different parts of the problem. A signed timestamp limits how long a request remains acceptable; a stable event or message ID lets your application recognize a duplicate even if it arrives within that time window. Neither control is a substitute for signature verification.
Implement the controls in this order
- Keep the original body. Read and preserve the raw request bytes for verification. Do not parse and re-serialize JSON, change whitespace, or otherwise normalize the body first: even semantically equivalent JSON can produce different signed bytes. Obtain the secret or key and signature headers configured for that endpoint.
- Verify with the provider’s scheme. Prefer the provider’s official verification library when available. Check that the signed input covers the raw body and timestamp; where the protocol supports it, ensure it also binds a message or event ID. Do not invent a signature format or assume another provider’s headers are interchangeable.
- Enforce freshness. After signature verification, compare the authenticated timestamp with a synchronized server clock. Reject timestamps outside a deliberate past-and-future tolerance. Choose a window based on the provider’s protocol, delivery behavior, and your clock-drift and delay requirements; there is no universal safe value. Keep clocks synchronized, for example with NTP where appropriate.
- Atomically claim the event ID. Once the signature and timestamp pass, insert or claim the stable authenticated event/message ID in durable storage under a uniqueness constraint. If another request has already claimed that ID, treat it as a duplicate and return the provider-appropriate success response without repeating the business action.
- Make acceptance durable before acknowledging. Where practical, commit the deduplication record with the related local state change in one transaction. For asynchronous or external work, use a transactional outbox or equivalent durable handoff so a successful acknowledgement does not precede durable acceptance. The exact transaction design depends on your database and side effects.
- Set an intentional retention period. Keep IDs at least as long as needed for the accepted replay window and provider retry or redelivery behavior. A short timestamp window can reduce how long IDs must be retained for replay-window protection, but business-level duplicate prevention and manual recovery may justify longer retention.
- Acknowledge promptly. Move complex work to an appropriate asynchronous process after durable acceptance. Delivery expectations differ by provider: GitHub advises returning a 2xx response within 10 seconds, while Stripe recommends quickly returning a 2xx before complex work.
Provider details that affect the design
| Provider or guidance | Timestamp and signature | Identifier and retry behavior | What to account for |
|---|---|---|---|
| Stripe | Stripe’s manual verification format signs the timestamp, a period, and the JSON request body with HMAC-SHA256. Its libraries use a default five-minute tolerance; it can be changed. Stripe advises synchronizing server time with NTP and warns that a tolerance of zero disables the recency check. | Each retry receives a new signature and timestamp. Stripe recommends tracking event IDs to avoid processing already-logged events. Event delivery order is not guaranteed. | Timestamp freshness does not identify a repeated business event. Maintain event-level idempotency and do not rely on arrival order. Stripe Webhooks documentation. |
| GitHub | GitHub recommends HTTPS and a high-entropy webhook secret; its best-practices page also describes optionally allowlisting current delivery IPs. | X-GitHub-Delivery can be used to identify a delivery uniquely per event; a requested redelivery uses the same value. |
The cited best-practices page does not establish that this header is part of the HMAC input. Do not treat it as a cryptographically authenticated nonce based on that documentation alone. GitHub webhook best practices. |
| Svix / Standard Webhooks-style guidance | The receiving guide describes Webhook-Id, Webhook-Timestamp, and Webhook-Signature. Its signed content concatenates the ID, timestamp, and raw body; its libraries reject timestamps more than five minutes in the past or future. |
IDs are unique per message and retained across retries. | This is a vendor implementation example, not a universal webhook standard. The guide recommends raw bytes for verification and a constant-time comparison. Svix receiving guide. |
Choose a freshness window and ID-retention policy
Do not copy a timestamp tolerance from another provider without checking what its SDK and delivery system actually do. Stripe’s five-minute default is a library setting, and Svix’s five-minute past-or-future rejection is behavior documented for its libraries; neither establishes a universal rule. A stricter window reduces the period in which a captured request could pass freshness validation, but a window that is too tight can reject legitimate delayed deliveries or requests affected by clock drift.
#1 Best Overall
- Durable:The Anti-theft hooks are very sturdy and strong which makes of two 5.5 Diameter double steel wires So they are greatly sturdy to hang heavy stuff
- Install Easily:Remove Anti-theft hooks cap from Hook and Set it into the slot or hole on the panel Then lock the cap to the end of the hook
- Various Usable : Hooks Perfectly hold all kinds of items for any places used for retail store Exhibiton products especial for Cellphone accessories even your garage , and etc.
- Extremely Beautify space and Save zoom: Display Hooks are nice display fixture to manage and organize different small important needs in your home or shop shelves . They would save your 70% zoom,So the Security panel display hooks are ideal tools for organize your cellphone accessories or any items in your store & home ,let you have no trouble of mess .Beautify any spaces and save your 70% zoom as well.
- More Safety :The Anti-theft hooks have no shapes ,burrs and are polisthed by machine with Chrome plated Which are accord with environmental standard So they are safe for touching
Retention has two related but distinct purposes. Keeping an ID long enough to cover the accepted timestamp window helps catch replays that remain fresh. Retaining it longer may be necessary to prevent duplicate business effects from provider retries, manual redeliveries, recovery jobs, or repeated delivery outside that narrow window. Set the policy using the provider’s actual retry and redelivery behavior and your application’s business requirements.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Make duplicate handling safe under concurrency
A check-then-act pattern is unsafe when two copies arrive at nearly the same time: both workers can check that an ID is absent before either records it, then both perform the action. Use an atomic insert or claim enforced by a unique key. Only the request that successfully claims the ID should proceed with the non-idempotent effect; a uniqueness conflict should follow the duplicate path.
If the event changes local records, a database transaction can tie the claim and state change together. If processing includes a queue or an external service, persist a durable handoff, such as an outbox entry, with the claim before acknowledging. The worker and any downstream operation may also need idempotency, because durable delivery systems can retry work after a timeout or crash.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesCommon implementation mistakes
- Parsing before verification: JSON parsing and re-serialization can alter the bytes the signature was calculated over.
- Checking an unsigned timestamp: If the timestamp is not covered by the signature, an intermediary could change it to make an old request appear fresh.
- Using freshness as deduplication: A replay inside the tolerance window can still pass. Use a stable event or message ID as well.
- Using a non-atomic duplicate check: Concurrent deliveries can both pass a separate lookup and trigger the action.
- Assuming every provider retries the same way: Stripe changes the attempt timestamp and signature on retries; GitHub says a requested redelivery reuses its delivery ID. Preserve idempotent business behavior while applying the provider-specific rules.
- Assuming header names imply trust: Confirm from the provider’s protocol whether an identifier is included in the signed input or otherwise authenticated before relying on it as a security control.
- Disabling recency validation: For Stripe, a tolerance of zero disables the recency check rather than making it stricter.
Operational checks before release
- Confirm the endpoint uses the correct provider secret and verifies the raw request bytes.
- Test that changing the body or signed timestamp makes verification fail.
- Test rejection of timestamps on both sides of the configured tolerance and verify the server clock remains synchronized.
- Submit the same valid event twice, including concurrently, and confirm only one business action occurs.
- Confirm duplicate requests receive a response appropriate to the provider so retries do not continue unnecessarily.
- Verify ID retention covers the delivery and recovery behavior you intend to support, not just the normal timestamp window.
For the timestamp-plus-identifier rationale, see Svix’s replay and signature failure guidance.
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.




