Skip to content

[Bug]: Unauthenticated GitHub Webhook DoS via Large Request Bodies #196

Description

@jonathanchang31

Summary

The webhook route is explicitly excluded from API rate limiting, and it reads the full request body (await c.req.text()) before failing invalid signatures.
An attacker can send many very large unauthenticated requests to force expensive body parsing/hashing work and consume worker CPU/memory/bandwidth.

Expected Result

  • Invalid/abusive webhook traffic should be rejected cheaply and early, with strict request-size limits and dedicated rate-limiting/protection.

Actual Result

  • Requests are unauthenticated and unthrottled at route level.
  • Worker still spends significant time processing each huge request before returning 401 invalid_signature.

Reproduction

  1. Start project locally with required runtime:
    export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"; nvm use 22
    npm install
    npm run cf-typegen
    npm run db:migrate:local
    npx wrangler dev --local --ip 127.0.0.1 --port 8787
  2. Create a large request body (50 MB example):
    python3 - <<'PY'
    with open('/tmp/payload50m.json','w') as fp:
        fp.write('{"x":"' + ('A' * (50*1024*1024)) + '"}')
    PY
  3. Send invalid-signature webhook requests (no valid x-hub-signature-256):
    /usr/bin/time -f 'single_request_time=%E' \
    curl -s -o /tmp/webhook_resp.txt -w 'http=%{http_code} size=%{size_download}\n' \
    -X POST http://127.0.0.1:8787/v1/github/webhook \
    -H 'x-github-delivery: big1' -H 'x-github-event: push' \
    --data-binary @/tmp/payload50m.json
  4. Stress concurrently:
    seq 1 8 | xargs -I{} -P8 sh -c \
    "curl -s -o /tmp/wresp_{}.txt -w '%{http_code} %{time_total}\n' \
    -X POST http://127.0.0.1:8787/v1/github/webhook \
    -H 'x-github-delivery: flood{}' -H 'x-github-event: push' \
    --data-binary @/tmp/payload50m.json"

Security/Business Impact

  • External attackers can generate high resource consumption without valid credentials.
  • Increased latency and potential degraded availability under flood conditions.
  • Higher infrastructure cost from unnecessary ingress/compute on invalid traffic.

Suggested Fix

  • Add strict request size enforcement for webhook (fail fast on Content-Length and streaming size cap).
  • Add dedicated webhook rate limiting (per IP / per delivery id / WAF rule).
  • Reject clearly invalid signatures before reading huge bodies when possible (header sanity checks + hard size gate first).
  • Consider Cloudflare-level protections (WAF/body size limits/bot rules) specifically for /v1/github/webhook.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions