Replay Protection
Timestamp validation prevents replay attacks on webhooks.
The threat
Without replay protection, an attacker who intercepts a valid webhook could resend it later. The signature would still be valid because the payload and secret haven't changed.
How CueAPI prevents replays
Every webhook signature is bound to a timestamp:
Signed content: "{timestamp}.{payload}"
The timestamp is sent in the X-CueAPI-Timestamp header. When verifying:
- Parse the timestamp from the header
- Check that
|now - timestamp| < tolerance(default: 5 minutes) - If the timestamp is too old or too far in the future, reject the webhook
Tolerance window
The default tolerance is 300 seconds (5 minutes). This allows for:
- Network latency
- Clock skew between CueAPI and your server
- Reasonable processing delays
Replays older than 5 minutes are automatically rejected.
Implementation
python
def verify_webhook(payload, secret, signature, timestamp, tolerance=300):
# Check timestamp freshness
ts = int(timestamp)
if abs(time.time() - ts) > tolerance:
return False # Too old — possible replay
# Verify signature (as normal)
...Combining with idempotency
For maximum security, combine replay protection with idempotency checks:
- Timestamp check — reject old webhooks (replay protection)
- Execution ID check — reject already-processed webhooks (idempotency)
This provides defense-in-depth against both replay attacks and duplicate deliveries.