Webhook endpoints return 200 OK quickly before complex processing
Why it matters
Stripe's webhook delivery has a 30-second timeout per attempt. If your webhook handler performs multiple sequential database writes, sends email via an external API, updates inventory, and calls third-party fulfillment services before returning 200, the total latency can easily exceed 30 seconds under normal load — and will exceed it under any database contention or external service slowdown. Stripe then marks the delivery as failed and retries, causing your handler to run again on the same event. Without idempotency guards, these retries create duplicate orders, duplicate emails, and duplicate inventory decrements. CWE-400 (Uncontrolled Resource Consumption) captures the timeout-induced retry cascade.
Severity rationale
Low because excessive synchronous processing before returning 200 causes Stripe to retry the webhook, and without idempotency guards those retries produce duplicate orders and emails.
Remediation
Return 200 immediately after signature verification, then dispatch heavy work to a job queue for asynchronous processing.
// app/api/webhooks/stripe/route.ts
export async function POST(req: Request) {
const body = await req.text()
const sig = (await 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 })
}
// Enqueue for async processing — lightweight, unlikely to timeout
await queue.enqueue({ type: 'stripe-event', event })
return new Response('OK', { status: 200 }) // Stripe receives 200 within milliseconds
}
Use Inngest, QStash, or BullMQ for the queue. The queue worker handles database writes, email, and fulfillment with its own retry logic — separate from Stripe's retry mechanism.
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 Payment Security Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-400 — Uncontrolled Resource Consumption
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-payment-security·automated