Verify the original bytes

Webhook signatures are commonly calculated over the raw request body. If JSON middleware parses and serializes the payload first, whitespace or ordering may change and a legitimate signature will fail.

Capture the raw body before parsing and use the provider’s maintained library. Keep test and production endpoint secrets separate. During rotation, allow a short overlap in which old and new secrets can verify deliveries.

A signature can be replayed

An attacker who captures a valid payload and signature can send them again. Verify the signed timestamp and accept only a small clock tolerance. That reduces the replay window, but legitimate delivery retries still remain part of the protocol.

Make processing idempotent. Store the event id under a uniqueness constraint and let duplicates finish without repeating a charge, email, entitlement change, or irreversible transition.

  • Verify signature and freshness before reading business fields.
  • Return a successful response quickly and queue expensive work.
  • Do not assume strict event ordering.
  • Log the event id and result, not the reusable signing material.

Design for at-least-once delivery

Providers retry when your endpoint times out or returns an error. If the handler changed data but failed before responding, the next attempt must not repeat the effect.

A mature webhook flow resembles a small distributed system: authenticity, deduplication, durable queues, observability, and recovery matter more than a beautifully short controller.

← Back to the archive