Raw card numbers (PAN) are never sent to the backend; tokenization is used
Why it matters
When raw card numbers (PAN), expiry dates, or CVC codes pass through your server, you become a PCI DSS SAQ D merchant — the most burdensome compliance tier, requiring quarterly penetration tests, annual on-site audits, and over 200 individual controls. PCI-DSS 4.0 Req 3.3 prohibits storing sensitive authentication data after authorization, and Req 4.2 prohibits transmitting cardholder data over open networks without strong encryption. OWASP A02 (Cryptographic Failures) treats cleartext card transit as a critical data exposure. Beyond compliance, any server-side log, crash report, or debug middleware that captures request bodies will inadvertently record card numbers — a single data breach then exposes millions of records.
Severity rationale
Critical because routing raw card numbers through your server places you in PCI SAQ D scope and creates multiple exfiltration vectors — logs, APM tools, error trackers, and database query logs can all capture card data in transit.
Remediation
Use Stripe Elements or the PaymentElement to tokenize card data in the browser. Your server should only ever receive the opaque pm_xxx or pi_xxx identifier.
// WRONG — card data sent to your server
await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ cardNumber: '4242...', cvc: '123', expMonth: 12, expYear: 2026 })
})
// CORRECT — only the token reaches your server
const { paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement)!,
})
await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ paymentMethodId: paymentMethod.id })
})
Audit every API route handler that accepts payment or checkout POST bodies — none of them should have fields named cardNumber, pan, cvc, cvv, expiry, or expMonth.
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-319 — Cleartext Transmission of Sensitive Information
- cwe · CWE-312 — Cleartext Storage of Sensitive Information
- owasp:2021 · A02
- pci-dss:4.0 · Req 3.3 — Sensitive authentication data not retained after authorization
- pci-dss:4.0 · Req 4.2 — PAN protected with strong cryptography during transmission
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-payment-security·automated