Webhooks & Events

Securing Webhook Endpoints

Your webhook URL is open to the internet. Treat it as a front door and lock it properly.

What you'll learn

  • Enumerate the threats a public webhook endpoint faces
  • Apply signature verification as the primary defence
  • Use HTTPS, timestamps, and rate limits as layers
  • Limit what a compromised payload could achieve

7 min read

The threat model

A webhook endpoint is, by necessity, a public URL that accepts POST requests and acts on what they contain. That combination makes it an attractive target worth thinking about carefully. The main threats are spoofing (an attacker sending fabricated events), tampering (altering a genuine event somewhere in transit), and replay (capturing one valid request and resending it later). On top of those, there is plain abuse — flooding the endpoint with traffic in an attempt to overload it.

Naming the threats explicitly clarifies the defences, because each one maps to a well-understood countermeasure. Layering those countermeasures means that no single failure leaves you exposed. The overarching goal is simple to state: any request you actually act on should be provably genuine, provably fresh, and provably intact, and anything that fails those tests is rejected.

Verify signatures first

The cornerstone defence, above all others, is signature verification: confirm that each delivery carries a valid signature computed with the shared secret before you trust a single field in it. This one check defeats both spoofing and tampering simultaneously, because a forged or altered request simply cannot produce a signature that matches what the provider would have generated.

Verify against the raw body using a constant-time comparison, and reject anything that does not match cleanly. Everything else in this list is a supporting layer arranged around this core; without the signature check, the other measures protect very little. The full mechanics, including the common raw-body pitfall, are covered in verifying webhook signatures, which every endpoint should implement first.

Add transport and timing layers

Always serve the endpoint over HTTPS so that payloads and their signatures are encrypted while in transit and cannot be read or altered on the wire. Include the timestamp in the value you verify and reject deliveries that are too old, which blunts replay attacks by giving captured requests a short shelf life. Apply rate limiting as well, so that a flood of requests cannot exhaust your resources and take the endpoint down.

Keep the signing secret itself well out of source control, and rotate it promptly if you ever suspect it has been exposed. These measures are individually cheap and they complement the signature check rather than replacing it. None of them is sufficient on its own, but taken together they make the endpoint considerably harder to abuse than any single one would.

Minimise the blast radius

Defence in depth assumes that any one layer might eventually fail, so the final principle is to limit what a single request can possibly achieve even if it slips through. Give the webhook processor only the permissions it genuinely needs and no more, validate every payload against a strict schema, and never let raw event data drive dangerous operations without checking it first. Least privilege turns a breach into a contained nuisance rather than a catastrophe.

Keep an audit log of deliveries and the actions each one triggered, so that you can investigate anomalies after the fact and spot patterns of probing. For the provider's specific signing scheme, header names, and any guidance on source IP ranges, consult the API documentation and align your endpoint's expectations with what it actually sends.

Key takeaways

  • A public endpoint faces spoofing, tampering, replay, and abuse
  • Signature verification is the primary, non-negotiable defence
  • HTTPS, timestamp checks, and rate limits add protective layers
  • Least privilege and strict validation limit any breach's impact

FAQ

Is HTTPS enough to secure a webhook endpoint?

No. HTTPS encrypts traffic but does not authenticate the sender. You still need signature verification to prove a request genuinely came from the provider.

How do I stop replay attacks?

Verify a timestamp included in the signed payload and reject deliveries that are too old. Combine this with idempotency so a replayed event has no extra effect.

Where should the signing secret live?

In a secret manager or environment configuration, never in source control. Restrict access to it and rotate it promptly if you suspect it has been exposed.

Integrate with Merion

Ready to build?

Read the API reference, grab the OpenAPI spec, and ship a resilient integration.