Webhook Security Testing: SSRF, Replay Attacks, and Signature Bypass

Webhooks are everywhere. Payment processors, CI/CD platforms, SaaS integrations — virtually every modern application either sends or receives webhooks. From a security perspective, webhooks represent two distinct attack surfaces: the inbound consumer (your endpoint that receives events from a third party) and the outbound sender (your system that pushes events to a user-configured URL). Both sides have critical vulnerabilities that are frequently overlooked.

This guide covers the full webhook attack surface — what breaks, how to test it, and what secure implementations look like.

Webhook Architecture: Two Attack Surfaces

Before testing, understand which side of the webhook you're dealing with:

Side Role Primary Risks
Outbound (sender) Your app pushes events to a user-registered URL SSRF via webhook URL, secrets in payloads, no delivery retries
Inbound (consumer) Your endpoint receives events from GitHub, Stripe, etc. Signature bypass, replay attacks, event injection, DoS

Most applications have both. A SaaS platform might let customers register webhook URLs (outbound) while also consuming webhooks from Stripe for payment events (inbound).

Outbound Webhook Vulnerabilities

SSRF via User-Controlled Webhook URL

When users register a webhook URL in your application and the server fetches that URL to deliver events, you have a classic Server-Side Request Forgery (SSRF) vector. The server makes an outbound HTTP request to an attacker-controlled URL — which can be pointed at internal infrastructure.

Attack scenario Register a webhook URL pointing at internal metadata services or private IP ranges. When the application fires the webhook, it sends an HTTP POST to the attacker's chosen destination — potentially exfiltrating cloud credentials.

Test cases:

Secure implementation: Validate the URL against an allowlist of schemes (https only), resolve DNS before making the request and reject private IP ranges, and use a dedicated outbound network segment without internal access.

Secrets Leakage in Webhook Payloads

Webhook payloads often contain sensitive event data. Test whether your outbound webhooks include more data than necessary — PII, internal IDs, or fields that shouldn't be shared with external consumers.

Missing Delivery Confirmation

Applications that don't verify webhook delivery can be exploited for event injection — an attacker can replay or forge events if the receiver can't distinguish legitimate deliveries from attacker-crafted requests.

Inbound Webhook Vulnerabilities

Signature Validation Bypass

Most webhook providers (GitHub, Stripe, Twilio) sign payloads using HMAC-SHA256. Your endpoint is supposed to verify this signature before processing the event. Failure to validate — or validating incorrectly — allows event injection.

Common bypass patterns:

Missing validation The endpoint processes any POST request without checking the signature header at all. Test by sending a fabricated payload without the signature header.
Timing attack Signature compared with string equality instead of constant-time comparison. == short-circuits on the first mismatched byte, leaking information about correct signature bytes. Always use hmac.compare_digest() (Python) or equivalent.
Wrong body used for verification Some frameworks auto-parse JSON before the signature check runs. The HMAC is computed over the raw request body (exact bytes), but the framework re-serializes the parsed object — whitespace, key ordering, or encoding differences cause the check to fail silently and fall back to unverified processing.
Algorithm confusion Provider sends sha256=<hash>. Application extracts everything after = and validates but doesn't check the prefix. Attacker sends sha1=<weak-hash> and the application accepts it if it also validates the body against SHA-1.

Test approach:

# Send event with no signature header
curl -X POST https://yourapp.com/webhooks/github \
  -H "Content-Type: application/json" \
  -d '{"action": "push", "repository": {"full_name": "attacker/repo"}}'

# Send event with wrong signature
curl -X POST https://yourapp.com/webhooks/github \
  -H "X-Hub-Signature-256: sha256=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
  -H "Content-Type: application/json" \
  -d '{"action": "push"}'

# Test algorithm substitution
curl -X POST https://yourapp.com/webhooks/github \
  -H "X-Hub-Signature: sha1=da39a3ee5e6b4b0d3255bfef95601890afd80709" \
  -H "Content-Type: application/json" \
  -d '{}'

Replay Attack

Without a timestamp check and nonce validation, valid webhook payloads can be captured and replayed indefinitely. A legitimate payment event could be replayed to trigger duplicate processing — duplicate orders, double credit, or repeated provisioning actions.

Test: Capture a legitimate webhook delivery (from a test environment). Re-send the exact same payload and headers — including the valid signature — hours later. If it's processed, replay is possible.

Secure implementation:

# Stripe-style signature verification (Python)
import hmac, hashlib, time

def verify_stripe_signature(payload_body, sig_header, secret, tolerance=300):
    parts = dict(p.split('=', 1) for p in sig_header.split(','))
    timestamp = int(parts['t'])
    signatures = [v for k, v in parts.items() if k == 'v1']

    # Reject stale events
    if abs(time.time() - timestamp) > tolerance:
        raise ValueError("Timestamp outside tolerance window")

    signed_payload = f"{timestamp}.{payload_body.decode()}"
    expected = hmac.new(
        secret.encode(), signed_payload.encode(), hashlib.sha256
    ).hexdigest()

    if not any(hmac.compare_digest(expected, sig) for sig in signatures):
        raise ValueError("Signature mismatch")

Event Injection via Forged Payloads

If signature validation is missing or bypassable, attackers can send crafted events to trigger application logic. Common targets:

Webhook Event Type Confusion

Applications that trust the event.type field in the payload without verifying it against what the endpoint expects can be tricked into processing the wrong event type.

Test: Send a webhook payload with a mismatched event type. For example, send a charge.refunded payload to an endpoint that's only supposed to handle charge.succeeded events. If it processes the event anyway, the application isn't verifying event type against expected type.

DoS via Webhook Flooding

Webhook endpoints are often not rate-limited. An attacker with a valid sender account can fire thousands of events per second, overwhelming the endpoint or triggering expensive downstream processing.

Webhook Registration Security

Applications that allow users to register webhook URLs need additional controls:

Control Why It Matters How to Test
URL validation Prevents SSRF Register private IPs, localhost, cloud metadata endpoints
HTTPS enforcement Prevents payload interception in transit Register http:// URL and verify it's rejected
URL ownership verification Prevents webhooks being sent to third-party URLs Register a URL you don't control; check if app verifies you own it
Secret rotation Limits exposure after credential leak Verify users can rotate the signing secret without losing history
Tenant isolation Prevents tenant A from receiving tenant B's events Check if webhook events are scoped to the correct tenant context

Testing Webhook Security with Burp Suite

# 1. Intercept outbound webhook requests
# Set up Burp as upstream proxy for your test environment
# Trigger webhook events and observe the outbound request

# 2. Test signature bypass
# Capture a legitimate webhook delivery in Burp HTTP history
# Modify the payload body and resend with original signature
# If accepted: signature is not validated or validated incorrectly

# 3. Test replay (using Burp Repeater)
# Capture a valid webhook delivery
# Wait 10+ minutes, then replay from Repeater
# If accepted: no timestamp validation

# 4. SSRF via webhook URL (using Burp Collaborator)
# Register a Burp Collaborator URL as a webhook endpoint
# Trigger delivery — observe DNS/HTTP interactions in Collaborator
# Pivot to internal IPs once SSRF is confirmed

Webhook Security Testing Checklist

Ironimo scans web applications with Kali Linux-grade tooling, including SSRF detection via webhook URL injection and API security testing. Run a scan without writing a custom test script.

Start free scan
← Back to Blog