Webhook signature verification is implemented
Why it matters
An unverified webhook endpoint is an open door for attackers to forge billing events — triggering subscription upgrades, skipping payments, or issuing refunds with no real money involved. CWE-345 (Insufficient Verification of Data Authenticity) is the exact failure; OWASP A08 (Software and Data Integrity Failures) and NIST SP 800-53 SI-7 (Software, Firmware, and Information Integrity) both call this out. Stripe's constructEvent() verifies an HMAC-SHA256 signature over the raw request body — if you parse the body to JSON first, the signature will never match, leaving you either always-failing or always-skipping the check.
Severity rationale
Critical because a missing or broken signature check lets any attacker forge payment confirmation events, enabling free access to paid features without a real payment.
Remediation
Read the raw request body before any JSON parsing, then verify the provider's HMAC signature before processing any event. In Next.js App Router, add export const dynamic = 'force-dynamic' to prevent static optimization from breaking body access.
// app/api/webhooks/stripe/route.ts
export const dynamic = 'force-dynamic'
export async function POST(req: Request) {
const body = await req.text() // raw body — must come before any JSON parse
const sig = req.headers.get('stripe-signature')!
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!)
} catch (err) {
return new Response('Invalid signature', { status: 400 })
}
switch (event.type) { /* handle events */ }
}
Set STRIPE_WEBHOOK_SECRET from stripe listen --print-secret (dev) or the Stripe Dashboard (prod).
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 Billing & Payments 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
- pci-dss:4.0 · Req 6.4.1 — Bespoke and custom software must be protected from web-based attacks
- owasp:2021 · A08 — Software and Data Integrity Failures
- nist:rev5 · SI-7 — Software, Firmware, and Information Integrity
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-billing·automated