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
- 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
- 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
- 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
- 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.
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
Actual Result
401 invalid_signature.Reproduction
x-hub-signature-256):Security/Business Impact
Suggested Fix
Content-Lengthand streaming size cap)./v1/github/webhook.