Slack webhook: rate-limit BEFORE HMAC verification
2026-05-07
What We Built
POST /webhooks/slack/action was registered before the global rate-limit chain. Every request triggered SHA256 HMAC computation on raw body — flood vector pinning CPU on HMAC with no throttle. Fixed by applying a per-IP rate limiter (60 req/min) at the top of the handler.
Why It Matters
CPU-pin DoS vector. HMAC over arbitrary-size body at unbounded RPS is a gift-wrapped resource exhaustion path.
How It Works
Route-local in-memory limiter. Four regression tests: floods return 429, rate-limit fires BEFORE HMAC verify, 429 includes Retry-After, different IPs tracked independently.
Lockstep Checklist
- [x] No API route changes (middleware/internal — lockstep N/A)
- [x] No SDK changes
- [x] No MCP tool changes
- [x] Regression test included (test-first invariant per /quality-fleet protocol)
- [x] Linked to /quality-fleet R1 dashboard at
.quality/dashboard.md
Provenance
Auto-found by /quality-fleet R1 (2026-05-07) scanner round, fixed in fix-agent batch under "go for all of it" autonomy grant. PR #207 merged to main as commit 7aa805b06. Finding(s) tracked at .quality/findings.jsonl (entries: "a7f3c9b2e1d4"). Production-deployed via ECS task-def revision 732 series.