Webhook signatures bind the delivery timestamp #
The signature is now computed over the timestamp and the raw body together. Under the previous scheme it covered the body alone, which left a captured delivery replayable for as long as the endpoint accepted it.
Affected
webhook deliveries (all events)
Action required
Recompute the signature over timestamp and raw body, then reject deliveries older than your tolerance window. The previous scheme is accepted until the sunset date.
Sunset
Binding the timestamp into the signed payload means it cannot be altered without invalidating the signature, which is what makes an age check meaningful. Verify the signature first, then reject anything older than your tolerance; five minutes is comfortably wider than any legitimate delay and narrower than a useful replay window.
Both schemes are accepted during the transition. After the sunset date only the current one is.
Migration guidance
- signature = HMAC_SHA256(raw_body, signing_secret)
+ signature = HMAC_SHA256(timestamp + "." + raw_body, signing_secret)Verify against the raw request bytes rather than a re-serialized copy of the parsed JSON, and compare in constant time.