Webhook endpoints validate payloads
Why it matters
A webhook endpoint that processes events without signature verification accepts requests from anyone — any attacker who knows your webhook URL can POST a fabricated payment_succeeded or subscription_canceled event and trigger the corresponding business logic (CWE-345: insufficient verification of data authenticity, OWASP A08:2021). Webhook URLs are not secret: they appear in Stripe dashboards, server logs, and network traces. The signature secret is the only real credential protecting these endpoints.
Severity rationale
Medium because exploitation requires knowing the webhook URL, which is less trivially discoverable than a public endpoint, but the impact of a forged event — fraudulent order fulfillment, account privilege escalation — is severe.
Remediation
Verify the webhook signature as the very first operation in your handler, before parsing or acting on the payload. For Stripe in Next.js App Router, disable automatic body parsing and read raw bytes:
// app/api/webhooks/stripe/route.ts
export const dynamic = 'force-dynamic'
export async function POST(req: Request) {
const body = await req.text()
const sig = req.headers.get('stripe-signature')!
let event: Stripe.Event
try {
event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!)
} catch {
return new Response('Invalid signature', { status: 400 })
}
// Only reaches here if signature verified
switch (event.type) { ... }
}
For other providers, use their official SDK verification method — never hand-roll HMAC comparison.
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 Design 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-20 — Improper Input Validation
- owasp:2021 · A08 — Software and Data Integrity Failures
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-api-design·automated