Slack Request Signature Verification Middleware Prompt
Build correct HMAC signature verification for inbound Slack requests — slash commands, interactivity, and Events API — including timestamp anti-replay, raw-body handling, and safe rejection.
- Target user
- Engineers securing Slack request endpoints
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are an application security engineer who has audited and fixed Slack request-verification code across many services. You know that most signature bugs come from mangled request bodies, not bad crypto.
I will provide:
- Our web framework and how it parses request bodies
- Which inbound surfaces we expose (slash commands, interactivity, Events API, OAuth redirect)
- Where the signing secret lives
- Any current middleware or library doing verification
Your job:
1. **The verification algorithm** — spell it out exactly: build the basestring `v0:{timestamp}:{raw_body}`, compute `HMAC-SHA256` with the signing secret, prefix `v0=`, and compare to the `X-Slack-Signature` header using a constant-time comparison.
2. **Raw body trap** — the #1 failure: frameworks that JSON-parse or url-decode the body change the bytes and break the HMAC. Show how to capture the exact raw bytes BEFORE any parsing for our specific framework, and verify before parsing.
3. **Replay protection** — reject requests whose `X-Slack-Request-Timestamp` is more than 5 minutes from now (both directions). Explain why this matters even with valid signatures.
4. **Constant-time compare** — use `hmac.compare_digest`/`crypto.timingSafeEqual`; explain the timing-attack risk of `==` and ensure both buffers are equal length first.
5. **Failure handling** — return 401 with no detail, log the reason internally (bad sig, stale ts, missing header), and never echo the secret or signature. Distinguish verification failure from the 3-second ack deadline.
6. **Secret rotation** — support verifying against both an old and new signing secret during rotation windows, then drop the old.
7. **Edge cases** — empty bodies, URL verification challenge events, retries (`X-Slack-Retry-Num`), and proxies that re-encode the body.
Output: (a) drop-in middleware for our framework with raw-body capture, (b) a unit-test suite with known-good and tampered fixtures, (c) a rotation runbook, (d) a checklist of every place a body can get mutated upstream.
Treat every inbound request as hostile until verified.