Short answer: if your agent pays x402 endpoints with @x402/fetch or @x402/axios, make sure it runs 2.23.0 or later; the same floor applies to @x402/extensions if you use Sign-In-With-X and to @x402/svm if you run a Solana facilitator. Below those versions the default client would sign a payment for whatever amount a 402 response asked and could sign a login challenge for a site it never contacted, and a TypeScript Solana facilitator could accept a token approval as if it were a transfer. The fixes shipped in August; what's new is that the security firm that found them published its findings on 22 October 2026, and that there is no security advisory, so npm audit will not tell you and PyPI lists nothing either. After upgrading, set maxAmountPerPayment to the price you expect rather than a comfortable round figure, because a cap is not a price check.
This post is the checklist, as of 25 October 2026.
Some background: x402 lets an HTTP client, usually an AI agent, pay for a request in stablecoins. The server answers 402 Payment Required with one or more payment options (amount, token, network, recipient), the client signs one, and a facilitator settles it. The reference SDKs in TypeScript, Python and Go are maintained by the x402 Foundation, a Linux Foundation project to which Coinbase handed the protocol this year, as The Hacker News summarises. What the agent does with a 402 is decided by the client library, and that is where the flaws were.
What was found, and when
V12's write-up reports 25 findings from a review of the x402-foundation/x402 repository: 3 critical, 13 high and 9 medium or low. The timeline it gives: the 3 critical and 13 high findings were reported to the x402 team on 12 August 2026, the three critical ones were fixed by 20 August (The Hacker News dates the releases to 18 August), the 9 medium and low findings were reported on 9 September, and the post went public on 22 October. V12 validated the findings with local tests and says it submitted no live transaction; neither V12 nor the foundation has reported exploitation in the wild.
The three critical findings:
- No spending limit by default. The default client took the first supported option from the 402 (
accepts[0]) and signed it, with no per-payment or total budget. The server supplied the amount, token, recipient and network. V12 describes the attack: a small first payment reveals the wallet address, the server reads its balance, and the next 402 asks for all of it. The Hacker News adds the condition under which this bites: agents that sign payments automatically, in apps that set no limits of their own. - A login signature for another site. The Sign-In-With-X extension lets an agent log in by signing a message naming the site, the wallet and a one-time value. The automatic client signed whatever message arrived in a 402 without checking that its
domainandurimatched the site it had contacted, so a server could relay a login challenge from a third site and use the signature there. - An approval accepted as a payment (Solana, TypeScript). The facilitator code for the Solana
exactscheme checked that an instruction called an allowed token program and then parsed it as a transfer without checking the instruction type. A token approval has the same layout and differs in the first byte, so an approval, which moves no tokens, passed as a payment. V12's local test returnedisValid: true. The Python and Go facilitators already checked the type.
The fixes
The TypeScript changes are in the core changelog and the @x402/svm changelog under 2.23.0: client spend controls now default to "only recognized pegged assets are allowed with a $1 USD cap", and createSIWxPayload gains a "new required third argument: the final URL of the 402 response (after redirects)", with signing refused when the challenge's domain or uri origin differs from that URL's origin. The pull requests are #3124 (spend controls), #3133 (SIWx bound to the request origin) and #3132, which makes the Solana exact path require the TransferChecked discriminator, first data byte 12, which the PR describes as matching the Python and Go code. The Hacker News lists the matching Python and Go pull requests (#3154, #3156, #3192, #3193) and, as of 23 October, the current releases: 2.28.0 for the npm packages and the Go module, 2.25.0 for the Python package. Its version check of the published packages found the Solana fix in every @x402/svm release from 2.23.0 on.
Two more fixes in the same changelog are worth knowing if you sell through the TypeScript middleware: 2.22.0 closed "a paywall bypass where a backslash in a :param/[param] segment" let requests reach protected handlers unpaid, and 2.27.0 matched routes against both the escaped and decoded path, because a literal route "could previously be reached unpaid" by encoding the path separator. If your paid routes run anything older than 2.27.0, an unpaid request may be getting through.
The part that makes this a checklist rather than old news: the foundation's changelogs list the fixes without calling them security fixes, and there is no advisory. The Hacker News checked on 23 October that npm audit reported nothing for the last TypeScript releases before the fixes, and PyPI listed no vulnerabilities for the last Python release before them. A dependency scanner will keep saying your lockfile is clean.
What to do if you pay
- Check the versions in your lockfile, not in
package.json. The floors from the disclosure:@x402/fetchor@x402/axios2.23.0 (they pull a matching@x402/core);@x402/extensions2.23.0 if you use SIWx; Pythonx402and the Go module on their fixed releases. If you callcreateSIWxPayloadyourself rather than through@x402/fetchor@x402/axios, pass the URL of the 402 response, after redirects, as the new third argument. - Set the cap to the price you expect. The buyer quickstart states the default: "the x402 client only pays recognized USD-pegged assets (e.g. USDC) and caps each payment at $1." Override it with
spendControls: { maxAmountPerPayment: "$5" }in TypeScript,MaxAmountPerPaymentin Go,max_amount_per_paymentin Python. A dollar is a safe default for a library; it is not a sensible limit for an agent that buys $0.001 lookups, where it allows a thousandfold overcharge. - Opt into tokens deliberately.
allowedAssetslists the{ network, asset }pairs you will pay, each with an optional atomic cap; the default is the SDK's own list of pegged assets. The dollar cap applies to those default assets only, and an added asset without its own cap is uncapped, so give every entry one.spendControls: false(DisableSpendControls()in Go,spend_controls=Falsein Python) removes every control, including the asset list. The spend-controls pull request's own reviewer noted that upgrading "silently caps every existing client at $1/payment and default-asset-only", so if payments started failing after an upgrade, this is why; the fix is a cap that matches your prices, notfalse. - Compare the quote, not just the cap. A cap bounds the damage; it doesn't notice that a $0.01 resource asked for $0.10. The lifecycle hooks page documents
onBeforePaymentCreation(on_before_payment_creation,OnBeforePaymentCreation), which runs before the payment payload is created and cancels the payment when it returns{ abort: true, reason }; its Python and Go examples abort above a hard-coded amount. Use it to compareselectedRequirements(selected_requirementsin Python,ctx.Requirementsin Go: amount, asset, network,payTo) with the quote you accepted when you chose the endpoint. A bug report opened on 21 October against@x402/fetch2.28.0 shows why: in the reporter's black-box test on Base Sepolia, with settlement simulated, a resource priced at 0.01 USDC returned a 402 for 0.1 USDC and the client signed it, because the only guard that engaged was the spend limit and the amount was under it. The thread's one-line summary, from a commenter: "cap ≠ expectation." The issue was still open and unassigned as of 25 October. - Read the challenge before the first payment. The seven checks in x402 payment challenge: what to check before you pay cover the amount, the asset, the pay-to address and the timeout. The free x402 checker and the
preflight_checktool on the ToolVet MCP server run them without paying, and ToolVet's own scan compares each listing's live challenge with its advertised price: a live price more than 10% above the advertised one costs the listing its pricing points (how we check and score). As of 25 October 2026, 19:05 UTC, 535 of 106,986 listings carried the "charges more than its listed price" finding on the statistics page: a small share, and the one finding a spending cap alone would not catch.
Does overcharging happen on mainnet?
The only measurement we found is independent and comes with its author's caveats. Agentic Finance Graph looked at 32,605 settlements worth $18,950.78, from 12 to 23 October 2026, into the 80 Bazaar-listed sellers on Base with at least 20 settlements in that window. 1,126 settlements (3.5%) were at least ten times the seller's median; 25 were at least a hundred times the median and at least $1, worth $1,928.23 in total, from 13 payers to 7 sellers. The author is explicit that on-chain data cannot tell a hostile overcharge from tiered or usage-based pricing, and calls the figures a ceiling on the overcharge vector, not a count of overcharges. We read it the same way: oversized payments settle in normal business, and a per-payment cap in dollars does not distinguish them.
What to do if you sell or run a facilitator
Upgrade the server-side packages too. The route-matching fixes above apply to the TypeScript resource-server middleware; the TransferChecked check applies to TypeScript Solana facilitators, and the Hacker News notes that the facilitator, not the attacker, paid the transaction fee for each accepted approval. If you run a Solana facilitator from a fork, diff your exact verifier against #3132.
For every role, the rule in V12's post is the one to keep: "Optional policies only protect applications that actually enable them." The August releases turned the spending limit from an option into a default. The expectation check is still yours to write.
Frequently asked questions
Which x402 SDK versions are affected by the V12 findings?
Clients before @x402/fetch or @x402/axios 2.23.0 had no default spending limit and signed Sign-In-With-X messages without checking the site; @x402/svm before 2.23.0 accepted a Solana token approval as a transfer. The Python and Go SDKs had the spending-limit and SIWx flaws but not the Solana one; neither source names a minimum Python or Go version, so check that your release contains pull requests #3154 or #3156 and #3192 or #3193. As of 23 October 2026 the current releases were 2.28.0 (npm and Go) and 2.25.0 (Python).
Why doesn't npm audit show the x402 vulnerabilities?
Because no security advisory has been published for them. The fixes appear in the changelogs as ordinary features and fixes, so audit tools, which read advisory databases, have nothing to match. Check the versions in your lockfile against the floors above instead.
What is the default x402 spending limit after the fix?
$1 per payment, in recognised USD-pegged stablecoins such as USDC. Set maxAmountPerPayment to the price you expect, list other tokens in allowedAssets, and avoid spendControls: false, which removes every control at once.
Does a spending cap stop an x402 API from overcharging my agent?
Only above the cap. Any amount under it is signed, including ten times the usual price of a cheap resource. To catch that, compare the challenge with the quote you accepted in onBeforePaymentCreation, or run the challenge through a preflight check before the first payment.
The counts above are as of 25 October 2026. How we check and score explains how ToolVet checks endpoints without paying them and how the price comparison works.