What Happens When Academics Stress-Test 15 x402 Payment Gateways: An Operator's Security Audit
Last week, researchers from EPFL, Zhejiang University, and USENIX Security 2026 dropped a paper that should make every x402 operator stop and audit their code: 31 security vulnerabilities across 15 facilitators, covering 99% of x402 transaction volume. Every single facilitator they tested violated at least one payment verification or settlement rule.
We run a facilitator in production. When the paper landed, we had two choices: skim the abstract and move on, or take it seriously and audit our own code against every attack class they described. We chose the latter.
Here's what we found, what we fixed, and a practical audit checklist for anyone operating an x402 payment gateway.
The Paper: A Quick Summary
The EPFL/Zhejiang team (arXiv:2607.19545) built an automated testing framework that systematically probes x402 payment gateways for violations of the protocol's three core guarantees:
- Payment verification — the facilitator must cryptographically verify that payment was made before delivering the service
- Settlement finality — once verified, the settlement must either succeed atomically or fail without delivering the service
- Resource protection — the facilitator must not allow attackers to consume paid resources without paying (gas abuse, replay, double-spend)
They classified attacks into four families:
| Attack Class | What It Exploits | Impact |
|---|---|---|
| Free Shopping | Settle failure → still serve. Invalid signatures accepted. Zero-amount payments pass. | Attacker gets paid service for free |
| Asset Theft | Facilitator wallet compromise. Refund-to-attacker. Settlement amount manipulation. | Attacker drains facilitator funds |
| Service Denial | Replay attacks. Sig reuse. Malicious payloads causing facilitator crash. | Legitimate agents can't pay or get service |
| Gas Abuse | Facilitator pays gas for malicious txns. Spam causing repeated on-chain ops. | Facilitator bleeds gas fees |
The paper confirmed that Coinbase, PayAI, and Mogami acknowledged and fixed 6 vulnerabilities in February 2026. But the broader finding — every facilitator had at least one vulnerability — is the real headline.
Our Audit: Methodology
We run a production x402 facilitator handling payment for 326 services. The codebase spans four files that matter for payment security:
- proxy.js (2,472 lines) — the main gateway: receives requests, checks trials/credits, forwards to services, injects payment headers
- x402.js (1,163 lines) — the payment engine: signature parsing, facilitator verify/settle, on-chain verification, receipt generation
- receipts.js — cryptographic receipt signing and verification
- payment.js — payment model: amount calculation, network routing
Our audit mapped each attack class from the paper to specific code paths, then traced every path manually to verify the control flow.
Free Shopping: The Most Critical Check
This is the big one. Free Shopping means "attacker gets paid service without paying." The paper found it in the majority of facilitators. The root cause is almost always the same pattern: settle failure after verify success, but the service is still delivered.
Here's the correct control flow for a paid request:
1. Parse payment from HTTP header 2. Call facilitator.verify(signature, amount, network) 3. If !verify.isValid → return 402 (don't serve) 4. Call facilitator.settle(verifiedPayment) 5. If !settle.success → return 402 (don't serve) ← THIS IS THE CRITICAL CHECK 6. Generate receipt 7. Forward request to service 8. Return service response + receipt
Step 5 is where most facilitators fail. They verify successfully (step 3), then if settlement fails (step 5), they either: (a) serve the content anyway — "the payment was verified, settlement will probably go through" (b) log an error and continue — "we'll reconcile later" (c) return a partial response — "here's a degraded version"
All three are Free Shopping vulnerabilities.
Our main proxy path (proxy.js → x402.js) passed this check: the processPayment() function properly returns null on settlement failure, and the caller returns 402 without forwarding the request. The primary payment path is secure.
What We Found: One Real Vulnerability
processPayment() function: when settlement failed, two code paths (gas and api-review endpoints) still delivered the service response instead of returning 402. The settlement call returned an error, but the function continued execution and returned the paid service data.
Here's what the vulnerable code pattern looked like (simplified):
// VULNERABLE PATTERN (simplified)
async function processPayment(payload, priceCents, networkId) {
// Step 1: Verify signature — this works correctly
const verifyResult = await facilitatorVerify(payload, priceCents, networkId);
if (!verifyResult || !verifyResult.isValid) {
return null; // ✅ Correct: no verify → no service
}
// Step 2: Settle — but settlement failure was NOT handled
const settleResult = await facilitatorSettle(verifyResult);
// ❌ BUG: settleResult could be null or failed, but code continues
// Step 3: Return paid service data
return {
receipt: generateReceipt(verifyResult),
data: await fetchServiceData(verifyResult.serviceEndpoint)
};
// ❌ Service delivered even when settlement failed
}
The fix was straightforward: check the settlement result and bail out if it failed:
// FIXED
async function processPayment(payload, priceCents, networkId) {
const verifyResult = await facilitatorVerify(payload, priceCents, networkId);
if (!verifyResult || !verifyResult.isValid) {
return null;
}
const settleResult = await facilitatorSettle(verifyResult);
if (!settleResult || !settleResult.success) {
console.error('[x402] SETTLE FAILED — returning 402, no service delivered');
return null; // ✅ Fixed: settle failure → no service
}
return {
receipt: generateReceipt(settleResult),
data: await fetchServiceData(verifyResult.serviceEndpoint)
};
}
This was a real bug. In the narrow window between verify and settle, if the facilitator returned a settlement error (network blip, facilitator-side issue, gas spike), the service would still be delivered. The attacker would get a paid API call for free.
We deployed the fix with zero-downtime reload, verified all four affected endpoints returned correct 402 responses, and the backup files are timestamped and stored.
Audit Results: Attack-by-Attack
Here's how our facilitator scored against every attack class in the paper:
| Attack Class | Status | Details |
|---|---|---|
| Free Shopping — settle failure | 🔴 Found & Fixed | Fixed in processPayment(); settle failure now returns null → 402 |
| Free Shopping — invalid sig | 🟢 Safe | facilitatorVerify() properly validates all signatures before returning isValid |
| Free Shopping — zero amount | 🟢 Safe | Minimum 1 cent enforced; schema.exact validation catches zero amounts |
| Asset Theft — wallet keys | 🟢 Safe | Platform wallet is env-var only; no private key in code or logs |
| Asset Theft — refund redirect | 🟡 Low Risk | Refunds go to payment source address (on-chain tx); facilitator wallet not used for refunds |
| Service Denial — sig replay | 🟢 Safe | sigUsed() / lockSig() dedup; each signature usable exactly once |
| Service Denial — tx replay | 🟢 Safe | txUsed() / lockTx() dedup per transaction hash |
| Gas Abuse — spam txns | 🟡 Mitigated | 5-min pending tx timeout; invalid txns cleaned without on-chain cost |
| Gas Abuse — malicious payload | 🟢 Safe | Amount validated client-side before any on-chain operation |
What Every x402 Operator Should Check
Based on this audit, here's a practical checklist for anyone running an x402 payment gateway:
1. Trace your settle failure path
This is the #1 vulnerability. Find every code path that calls settle, and verify that settle failure means no service delivery, no exceptions. Don't trust error handlers that "log and continue." Don't trust try/catch blocks that don't re-throw. The only acceptable behavior on settle failure is returning 402.
2. Signature deduplication is not optional
If your facilitator doesn't track used signatures (or nonces) and reject replays, an attacker can pay once and call the same paid endpoint infinitely. This is trivial to implement (a Set or Map of used sigs with TTL expiry) but catastrophic to miss.
3. Zero-amount transactions must be rejected
The x402 challenge format includes maxAmountRequired. Verify that your settlement code rejects zero-amount payments even if the facilitator says they're valid. A facilitator bug that accepts zero-amount settlements becomes a Free Shopping vulnerability downstream.
4. Receipts are not optional — they're accountability
The paper notes that facilitators without receipt generation can't provide dispute resolution. If an agent claims they paid but didn't get service, the facilitator has no evidence to resolve the dispute. Cryptographically signed receipts (linking payment txHash → service endpoint → response hash) are the foundation of accountability in agent payments.
5. Test your 402 responses in production
Set up a monitor that calls your endpoints with invalid signatures and verifies you get a proper 402 response (not a 200 with trial data, not a 500, not a timeout). The EPFL team built automated testers for this — you should too.
Why This Matters Beyond Security
The EPFL paper is a milestone for the x402 ecosystem. It's the first independent, academic security audit of the protocol in production — and it shows that the protocol design is sound (the attack surface is implementation errors, not protocol flaws).
But there's a bigger story here: security audits create trust, and trust is what's missing from agent-to-agent payments.
Right now, the biggest barrier to M2M payment adoption isn't technology. The payment rails work — Cloudflare, Coinbase, Stripe, and 40+ x402 Foundation members have proven that. The barrier is that agents (and their developers) don't trust the payment infrastructure. They don't know if their money is safe. They don't know if they'll get what they paid for. They don't know if there's recourse when something goes wrong.
Independent security audits — and operators who publicly share their results — are part of building that trust. Every facilitator that passes an audit and publishes the results makes the whole ecosystem stronger.
We're doing our part. If you run an x402 facilitator, we encourage you to do the same.
References
- EPFL / Zhejiang University / USENIX Security 2026 — "Systematic Security Analysis of x402 Payment Facilitators" (arXiv:2607.19545)
- CryptoSlate coverage: "31 x402 facilitator vulnerabilities found, 6 confirmed and patched by Coinbase, PayAI, and Mogami" (August 2026)
- x402 Protocol Specification — x402.org
- Cloudflare Wallets documentation — developers.cloudflare.com/wallets