- Symptom
- Invalid request signature on every request from SlackSignature matches in a unit test but not behind Express json() or body-parserRequests rejected after the server clock drifts
- Cause
- The HMAC is computed over v0:timestamp:raw body, so a body that was parsed and serialized again no longer matches byte for byte. Requests whose X-Slack-Request-Timestamp is more than five minutes from local time must be rejected.
- Fix
- Capture the raw body before any parser runs, compare with a constant-time function, and keep the server clock in sync with NTP.
- Apply
app.use("/slack/events", express.raw({ type: "*/*" })); const base = `v0:${ts}:${req.body.toString("utf8")}`; const sig = "v0=" + crypto.createHmac("sha256", secret).update(base).digest("hex"); crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.get("x-slack-signature")));- Affected
- Slack HTTP request verification with signing secret v0, all versions as of 2026-10
- Sources
Last verified 2026-10-15 · Confirmed by 0 builders