Skip to main content

Webhook Security Best Practices

Secure a webhook by signing every request with HMAC-SHA256 over the payload plus a timestamp, rejecting any request whose signature fails verification or whose timestamp is more than five minutes old, sending only over HTTPS, and routing outbound calls through a proxy that blocks internal IP ranges. Receivers should treat delivery as at-least-once and deduplicate by idempotency ID.

Building webhooks?
Svix is the enterprise ready webhooks sending service. With Svix, you can build a secure, reliable, and scalable webhook platform in minutes. Looking to send webhooks? Give it a try!

How to secure webhooks

Four controls cover the attacks webhooks are actually subject to:

  1. Sign the request. Compute an HMAC-SHA256 over the raw body, the timestamp, and a message ID, using a secret shared with that one endpoint, and send it in a header. Receivers recompute it and compare with a constant-time equality check.
  2. Include and check a timestamp. A five-minute tolerance is the common choice: old enough for clock skew, short enough that a captured request expires before it is useful.
  3. Filter outbound destinations. Resolve the endpoint URL and refuse private and link-local ranges, and run the sending workers where they cannot reach internal services.
  4. Require HTTPS. Reject http:// endpoints at registration rather than at send time, so the misconfiguration is caught by the person who can fix it.

The sections below explain what each control defends against.

Server-side request forgery (SSRF)

A Server-Side Request Forgery (SSRF) attack is when an attacker manipulates a server into reading or updating internal resources by supplying or altering a URL, which the server then calls. Webhook implementations are particularly vulnerable to SSRF as they allow consumers to add any URL they want, which will be accessed from the internal webhook system.

Preventing SSRF attacks primarily involves preventing webhooks from communicating with internal networks and services.

Best practices for preventing SSRF:

  1. Using a special proxy such as Smokescreen to filter internal IP addresses
  2. Placing the webhook workers (or proxy) in a separate private subnet with no access to internal services

Replay attacks: duplicating data transmissions

Replay attacks can be particularly problematic. A bad actor intercepts a valid request, modifies it, and then replays it.

Best practices for preventing replay attacks

  1. Add a timestamp to each webhook attempt and ensure that it falls within a specific tolerance.
  2. Implementing idempotency in your APIs can help ensure that webhook requests are only processed once, even if they are received multiple times.

Spoofing attacks

Attackers can impersonate services by sending a fake webhook to an endpoint, turning the very essence of webhooks, a simple HTTP POST, into a security vulnerability. The best way to prevent spoofing attacks is to sign your webhook requests. You can even take advantage of the timestamp and idempotency IDs that help with replay attacks.

Best practices for preventing spoofing attacks with webhook signatures:

  1. Include the payload and additional metadata like an idempotency ID and timestamp when signing the webhook
  2. Use HMAC-SHA256

Protecting against man-in-the-middle attacks

Man-in-the-middle (MITM) attacks occur when an attacker intercepts communications between two parties.

Best practice for preventing Man-in-the-Middle attacks:

  1. Always use HTTPS URLs, ensuring that the request is encrypted and the connection verified.

Putting the controls together

None of these controls is difficult on its own. The work is applying all four consistently, on every endpoint, for as long as the integration lives, including secret rotation and the audit trail that shows which delivery carried which signature. Svix implements this set by default, and Svix Play lets you inspect the signed requests your own service sends.