Webhook signatures verified
Why it matters
Unsigned webhooks let any attacker impersonate your event source and inject arbitrary payloads. CWE-345 (Insufficient Verification of Data Authenticity) and CWE-347 (Improper Verification of Cryptographic Signature) describe the failure. OWASP API Security Top 10 2023 API8 (Security Misconfiguration) covers unsigned webhook receipt as a trust boundary violation. Platforms like Stripe, GitHub, and Twilio all sign their webhooks with HMAC-SHA256 for this reason. Without signature verification, attackers who discover your webhook endpoint can send fake events — triggering account upgrades, order fulfillments, or permission changes — by simply POSTing correctly shaped JSON. Timing-safe comparison is required; string equality is vulnerable to timing attacks.
Severity rationale
Info severity because webhook forgery requires knowing your endpoint URL, but the impact — injecting arbitrary business events — can be critical to business logic.
Remediation
Compute and compare the HMAC-SHA256 signature using crypto.timingSafeEqual — regular string comparison leaks timing information that can be used to forge valid signatures bit by bit.
// src/app/api/webhooks/route.ts
import crypto from 'crypto'
export async function POST(req: Request) {
const rawBody = await req.text() // read as text before parsing
const sig = req.headers.get('x-webhook-signature') ?? ''
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET!)
.update(rawBody)
.digest('hex')
const sigBuffer = Buffer.from(sig, 'hex')
const expectedBuffer = Buffer.from(expected, 'hex')
// timingSafeEqual requires same-length buffers
if (sigBuffer.length !== expectedBuffer.length ||
!crypto.timingSafeEqual(sigBuffer, expectedBuffer)) {
return new Response('Unauthorized', { status: 401 })
}
const payload = JSON.parse(rawBody)
// ... process verified payload
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the API Security Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-345 — Insufficient Verification of Data Authenticity
- cwe · CWE-347 — Improper Verification of Cryptographic Signature
- owasp:2021 · A02 — Cryptographic Failures
- owasp:2023 · API8 — Security Misconfiguration
Taxons
History
- 2026-04-18·v1.0.0·Initial import from api-security·automated