Skip to main content
Webhook Security: Signature Verification, Replay Prevention, and Failure Handling — G8KEPR Blog
Back to Blog
Architecture8 min readApril 3, 2026

Webhook Security: Signature Verification, Replay Prevention, and Failure Handling

Webhooks are the most common unsecured integration point in SaaS architectures. An unverified webhook endpoint accepts any POST request from any source. Here is the complete security implementation: signature verification, timestamp validation, replay prevention, and idempotent processing.

A webhook is an HTTP POST to an endpoint you control, triggered by an event at a third-party service. Stripe sends a payment.succeeded event. GitHub sends a push event. PagerDuty sends an alert.triggered event. Your endpoint receives the POST and acts on it. The security question: how do you know the POST actually came from Stripe or GitHub and not from an attacker who knows your webhook URL?

Signature Verification

Every serious webhook provider signs their payloads with HMAC-SHA256 using a shared secret. Stripe includes a Stripe-Signature header; GitHub includes an X-Hub-Signature-256 header. Your endpoint must verify this signature before processing the event.

python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    # Constant-time comparison to prevent timing attacks
    return hmac.compare_digest(f"sha256={expected}", signature_header)

Timestamp Validation and Replay Prevention

Signature verification alone does not prevent replay attacks — an attacker who intercepts a legitimate signed webhook can re-submit it hours later. Include timestamp validation: reject any webhook with a timestamp older than 5 minutes. This limits the replay window to a period where the signature is still valid but the event has already been processed.

Idempotent Processing

Webhooks are delivered at-least-once — the sending service will retry on failure. Your endpoint will receive the same event multiple times. Make processing idempotent: use the event ID as a deduplication key, store processed event IDs in a cache or database, and skip processing for events you have already handled.

G8KEPR validates outbound webhook signatures for all event deliveries and includes an event ID and timestamp in every payload. Inbound webhook verification for connected integrations (Slack, PagerDuty, GitHub) is handled at the gateway layer.

ShareX / TwitterLinkedIn

Ready to secure your AI stack?

14-day free trial — full platform access, no credit card required. Early access members get pricing locked in forever.