Security researchers disclosed on 22 October 2026 that they found 25 vulnerabilities in x402, the HTTP payment protocol AI agents use to pay for APIs. Three were critical. The TypeScript fixes shipped in the @x402 npm packages at 2.23.0 on 18 August. Anyone running x402 clients, facilitators or Sign-In-With-X should upgrade every @x402 package together.
The three critical bugs each broke a different promise. A Solana payment check accepted a token approval as if it were a transfer, so a merchant could hand over a paid resource and receive nothing. An agent could be led to sign a wallet login for a website it never visited. And the documented default client had no spending limit, so a hostile server could ask an agent to authorise its whole token balance.
This post covers what the researchers published, a release timeline from the npm registry, affected and fixed versions per package, each bug class in plain language, how to check what you have installed and what to change in your code beyond the version bump. There is no exploit code here. For the same theme from the infrastructure side, autonomous agents running without limits, see our post on the Skynet LLMjacking agent.
What the researchers reported
The research team reviewed the x402 codebase and published a write-up focused on the three critical findings. In their words, each issue "crossed a different trust boundary": what counted as a payment, which website a signature was for, and who decided how much the wallet could spend.
| Item | Value | Source |
|---|---|---|
| Total vulnerabilities reported | 25 | Research write-up |
| Critical / high / medium and low | 3 / 13 / 9 | Research write-up |
| Critical and high findings reported to the x402 team | 12 August 2026 | Research write-up |
| Three criticals fixed, per the researchers | By 20 August 2026 | Research write-up |
| Medium and low findings submitted | 9 September 2026 | Research write-up |
| Public write-up | 22 October 2026 | Research write-up |
| CVE IDs or GitHub advisory for these findings | None found as of 23 October | Repository advisory page |
| Reported exploitation in the wild | None stated | Research write-up |
The write-up describes local tests, not attacks on live systems. For the Solana bug, the researchers say their test used the real token encoders and parser and confirmed the verifier returned a valid result for an approval, but did not submit a live transaction. For the login bug, they confirmed the real Sign-In with Ethereum library produced a correctly formatted message for an unrelated domain.
Only the three critical findings are described. The 13 high and 9 medium or low issues are counted but not detailed, so we cannot map them to specific changelog entries.
Timeline
Times are UTC. Package publish times come from the npm registry's time field. Pull request dates come from the GitHub pull request pages.
| Date and time (UTC) | Event | Source |
|---|---|---|
| 11 Aug 2026, 12:53 | Pull request 3124, "spend controls", opened by a maintainer | GitHub PR 3124 |
| 12 Aug 2026 | Researchers report the 3 critical and 13 high findings to the x402 team | Research write-up |
| 12 Aug 2026 | Pull request 3132, "require TransferChecked discriminator in svm exact", opened and merged | GitHub PR 3132 |
| 12 Aug 2026 | Pull request 3133, "bind SIWX client challenge to the request origin", opened | GitHub PR 3133 |
| 13 Aug 2026 | Pull requests 3124 and 3133 merged | GitHub PR 3124; PR 3133 |
| 18 Aug 2026, 20:33:59 | @x402/core 2.23.0 published | npm registry |
| 18 Aug 2026, 20:34:32 | @x402/extensions 2.23.0 published (SIWX origin binding) | npm registry; changelog |
| 18 Aug 2026, 20:36:32 | @x402/svm 2.23.0 published (TransferChecked guard, spend controls) | npm registry; changelog |
| 18 Aug 2026, 20:39 to 20:40 | @x402/evm, @x402/fetch, @x402/axios and @x402/mcp 2.23.0 published | npm registry |
| 18 Aug 2026 | Python x402 2.20.0 and Go v2.23.0 released with client spend controls | Python and Go changelogs |
| By 20 Aug 2026 | Three critical vulnerabilities fixed, per the researchers | Research write-up |
| 9 Sep 2026 | Researchers submit a further 9 medium and low findings | Research write-up |
| 22 Sep 2026, 18:26:45 | @x402/core 2.27.0 published with a separate encoded path separator fix | npm registry; changelog |
| 29 Sep 2026, 19:03:58 | @x402/core 2.28.0 published; latest at the time of writing | npm registry |
| 22 Oct 2026 | Research write-up published | Research write-up |
One timing detail: the spend controls pull request was opened on 11 August, a day before the date the researchers give for their report, and neither the pull request nor the changelog credits the research. It may have been work already in progress or earlier informal contact. It does not change what you should install.
How x402 works, briefly
x402 revives HTTP status 402, Payment Required. Per the project README and the v2 specification:
- A client, often an AI agent, requests a resource.
- The resource server answers 402 with a base64 encoded
PaymentRequiredobject in thePAYMENT-REQUIREDheader, listing accepted options: scheme, network, token, amount and recipient. - The client picks an option, signs a payment payload and retries with it in a
PAYMENT-SIGNATUREheader. - The server asks a facilitator to verify the payload, usually through its
/verifyendpoint. - If valid, the server does the work and settles, often through the facilitator's
/settleendpoint, which submits the transaction on chain.
The x402 documentation describes the facilitator as optional but recommended, so resource servers do not have to run blockchain infrastructure. Sign-In-With-X (SIWX) is an extension that lets a client prove it controls a wallet, so a returning agent can authenticate instead of paying again. On Ethereum chains it builds a standard EIP-4361 message.
The README says schemes "must not allow for the facilitator or resource server to move funds, other than in accordance with client intentions." The specification lists budget management for AI agents as "implementation-specific." The three critical bugs are three ways those intentions were not enforced in code.
The three critical findings
We describe each bug at the level a defender needs, without attack steps.
1. An approval was accepted as a payment
Where: the TypeScript Solana facilitator for the exact scheme, v1 and v2, per the researchers. This is facilitator side code in @x402/svm.
What should happen: the client builds a transaction that moves tokens to the merchant with the token program's TransferChecked instruction. The SVM exact scheme specification requires that "exactly one" transfer match the requirements: correct mint, correct destination token account, amount at least the price.
What went wrong: the fast path verifier read a fixed instruction position, confirmed it called an allowed token program, then decoded it as a transfer without first confirming it was one. Solana's documentation describes ApproveChecked as recording a delegate and an allowance on a token account. It grants permission to spend and moves nothing. Per the researchers, the two decode to the same fields, and the delegate landed where the verifier expected the destination. An approval naming the merchant's token account passed every check.
Impact, per the researchers: "a complete payment bypass." A merchant could deliver a paid resource and receive no tokens. The attacker needed a valid token account but no balance, and the facilitator paid the network fee, so repetition could drain both the merchant's resources and the facilitator's fee budget. The settlement code also skipped its post settlement payment check on this path.
The fix: pull request 3132 adds an explicit check that the first byte of the instruction data equals 12, the TransferChecked discriminator, matching what the Python and Go implementations already did. It shipped in @x402/svm 2.23.0.
2. A server could get a login signature for another website
Where: the SIWX client wrapper in the TypeScript SDK (@x402/extensions, used through @x402/core and the HTTP client packages).
What should happen: EIP-4361 says the domain in a Sign-In with Ethereum message "MUST correspond to the origin from where the signing request was made," and that wallets must verify it to prevent phishing. In a browser, the wallet reads that origin from the page. An automated x402 client has no browser, so the SDK has to play the wallet's role.
What went wrong: the automatic wrapper copied domain and uri from the server's 402 response straight into the message it signed, without checking them against the host the client had contacted.
Impact, per the researchers: session takeover. A hostile data server could relay a fresh login challenge from a site that accepts wallet sign in, collect the agent's signature and use it to log in there as the agent's wallet. The target's checks would pass, because the message really named the target and the signature was genuine. The damage is whatever that session allows, unrelated to the price of the original API call.
The fix: pull request 3133. From 2.23.0, createSIWxPayload takes a required third argument, the final URL of the 402 response after redirects, and refuses to sign when the challenge domain or uri origin does not match it. The SIWX specification now says the client "MUST refuse to sign" in that case.
3. The default client setup had no spending limit
Where: the TypeScript x402 client in its documented default configuration.
What went wrong: per the researchers, the default applied no per payment cap and no total budget. It selected the first supported option the server offered, and the server's amount, token, recipient and network flowed into the signing code. The HTTP decoding path also skipped the SDK's own schema validator, though the researchers stress that validation alone would not fix spending, since a well formed request can still ask for too much.
Impact, per the researchers: a hostile API could turn a routine data request into an authorisation for the wallet's full balance of a compatible token. With an automatic signer and no application policy, the client would sign it. The practical limits were the wallet balance and any external signer restrictions.
The fix: pull request 3124 adds client spendControls in 2.23.0. Per the changelog, by default only recognised pegged assets are allowed, with a $1 USD cap per payment. Teams opt into other tokens through allowedAssets, with an optional integer per asset cap in atomic units, or disable controls with spendControls: false. The paywall package disables them because a human approves in its UI; the MCP client forwards the setting.
Other payment bypass fixes from the same weeks
The @x402/core changelog lists more fixes in this period where a protected route could be reached without paying: a wildcard regex missing the dotAll flag (2.21.0), a backslash in a route parameter on Express and Hono (2.22.0), and an encoded path separator such as /api%2Fpremium reaching a literal route (2.27.0, credited to other contributors). The write-up does not say whether any of these are among its 25. The pattern is familiar from web frameworks: when the middleware that decides "is this route paid" parses a path differently from the router, requests fall through the gap. If you use the x402 HTTP middleware, go to the latest release, not the minimum fix for the three criticals.
Technical details
Values come from the research write-up, the x402 changelogs, the pull request pages and the npm registry, as attributed.
Affected and fixed versions, TypeScript
The write-up gives no version ranges. These are inferred from the changelogs: the fix commits landed in 2.23.0, so earlier 2.x releases lack them. Read "affected" as "lacks the fix," not as an advisory statement.
| Package | Finding | Lacks the fix | First fixed | Fix reference |
|---|---|---|---|---|
@x402/svm | Approval accepted as payment | 2.22.0 and earlier | 2.23.0 | PR 3132, commit 16a23d0 |
@x402/extensions | SIWX signs for another origin | 2.22.0 and earlier | 2.23.0 | PR 3133, commit c2612d3 |
@x402/core | SIWX origin plumbing (requestUrl) | 2.22.0 and earlier | 2.23.0 | PR 3133, commit c2612d3 |
@x402/core, @x402/svm, @x402/evm, @x402/mcp | No default spend limit | 2.22.0 and earlier | 2.23.0 | PR 3124, commit 4f58723 |
@x402/fetch | Picks up SIWX origin binding | 2.22.0 and earlier | 2.23.0 | Changelog references c2612d3 |
@x402/core | Encoded path separator (not tied to the 25) | 2.26.0 and earlier | 2.27.0 | PR 3542, commit 5d3a2b2 |
All @x402/* | Latest at time of writing | n/a | 2.28.0 | npm registry |
The @x402 packages release in lockstep. A 2.28.0 @x402/core beside a 2.22.0 @x402/svm still lacks the Solana guard.
Other runtimes
| Runtime | Spend controls | SIWX client origin binding | Solana discriminator check |
|---|---|---|---|
Python x402 | 2.20.0, 18 Aug 2026 | Python pull request referenced from PR 3133; not matched to a release | Already present, per PR 3132 |
Go github.com/x402-foundation/x402/go/v2 | v2.23.0, 18 Aug 2026 | Go pull request referenced from PR 3133; not matched to a release | Already present, per PR 3132 |
The bug classes, conceptually
| Finding | Bug class | Trust boundary | Missing check |
|---|---|---|---|
| Approval accepted as payment | Type confusion in instruction parsing | What counts as a payment | Confirm the instruction type before decoding it as a transfer |
| Login signature for another site | Confused deputy, missing origin binding | Which website a signature is for | Compare challenge origin to the URL actually contacted, before signing |
| No default spending limit | Unbounded authority from untrusted input | Who decides how much to spend | Enforce caps and token, network and recipient allowlists, before signing |
All three trust a field supplied by the other side. As the researchers put it, these checks "must run before the client signs or the facilitator accepts a payment."
The two Solana instructions
| Property | TransferChecked | ApproveChecked |
|---|---|---|
| Purpose (Solana docs) | Moves tokens between token accounts, verifying mint and decimals | Records a delegate and allowance on a token account, verifying mint and decimals |
| Moves funds | Yes | No |
| Discriminator (first data byte) | 12 (0x0c) | 13 (0x0d), per the researchers |
| Account in the slot the old verifier read as destination | Destination token account | Delegate |
API changes that come with the fixes
createSIWxPayload(serverExtension, signer, requestUrl): the third argument is new and required. Two argument calls must change.x402HTTPClient.handlePaymentRequirednow accepts the response URL and passes it to hooks asPaymentRequiredContext.requestUrl.spendControls: default allows recognised pegged assets with a $1 USD cap. Payments outside it are dropped unless you opt in throughallowedAssets. A non integer per asset cap is a configuration error.- Renamed constants:
DEFAULT_STABLECOINS,USDC_CONFIGandDEFAULT_ASSET_BY_NETWORKbecameDEFAULT_ASSETS; identifier fieldsaddressandasaIdbecameasset.
Identifiers and advisories
We found no CVE and no GitHub security advisory for these findings. The repository lists two older, unrelated advisories that are easy to confuse with this story:
| Advisory | Published | Package and range | Patched |
|---|---|---|---|
GHSA-qr2g-p6q7-w82m | 6 Mar 2026 | @x402/svm below 2.6.0; Python x402 below 2.3.0 | @x402/svm 2.6.0; Python 2.3.0; Go 2.5.0 |
GHSA-3j63-5h8p-gf7c | 20 Aug 2025 | x402, x402-express, x402-hono, x402-next below 0.5.2 | 0.5.2 |
The practical consequence: npm audit will not flag a vulnerable @x402 version for these findings, because there is no advisory record to match.
Who is affected
| You are | Exposed to | What to do |
|---|---|---|
| Running a TypeScript facilitator that settles Solana payments, or self facilitating | Approval accepted as payment | Upgrade @x402/svm and @x402/core; reconcile settlements on chain |
| A merchant using a hosted facilitator | Depends on its version | Ask which @x402 version it runs and when it upgraded |
| Running an agent that pays automatically with the TypeScript client | No default spend limit | Upgrade, then set explicit caps and allowlists |
| Running a client with SIWX and an automatic signer | Login signature for another site | Upgrade and pass the response URL to createSIWxPayload |
| Running an MCP server that pays for upstream APIs | Spend limit, and SIWX if enabled | Upgrade @x402/mcp; add policies to createx402MCPClient |
| Running a resource server with the x402 HTTP middleware | Route matching bypasses fixed through 2.27.0 | Upgrade to 2.28.0 |
| A site accepting Sign-In with Ethereum from agents | Relayed login challenges | Validate SIWX origin against configuration, not request headers |
Detection: step by step
1. Find every @x402 package
# Installed versions, including transitive ones
npm ls --all @x402/core @x402/svm @x402/evm @x402/extensions @x402/fetch @x402/axios @x402/mcp
# Every installed @x402 package and version, via npm's selector query
npm query '[name^="@x402/"]' | jq -r '.[] | "\(.name)@\(.version)"' | sort -u
# Why a package is present
npm explain @x402/core
pnpm why @x402/core
yarn why @x402/core
Across many repositories, read the lockfiles:
for f in $(find . -name package-lock.json -not -path '*/node_modules/*'); do
echo "== $f"
jq -r '.packages | to_entries[]
| select(.key | contains("node_modules/@x402/"))
| "\(.key) \(.value.version)"' "$f"
done
grep -rn --include=pnpm-lock.yaml "'@x402/" .
Also list the legacy v1 package names (x402, x402-fetch, x402-axios, x402-express); see Open questions.
2. Compare against the fixed versions
npm view @x402/core version
npm view @x402/svm time --json | jq -r '."2.23.0"'
npm outdated '@x402/core' '@x402/svm' '@x402/extensions'
Below 2.23.0 lacks the three critical fixes; below 2.27.0 lacks the encoded path fix; mixed @x402 versions need fixing even if @x402/core is current. Do not rely on npm audit here.
3. Search for patterns the upgrade does not fix
# SIWX payload creation still using two arguments
grep -rnE "createSIWxPayload\([^,()]+,[^,()]+\)" --include=*.ts --include=*.js src/
# Spend controls switched off
grep -rn "spendControls: *false" --include=*.ts --include=*.js src/
# Custom selectors or policies that may widen what gets signed
grep -rnE "paymentRequirementsSelector|policies *:" --include=*.ts --include=*.js src/
spendControls: false in a paywall where a human approves each payment is intended. The same line in an unattended agent is a finding.
4. Facilitators: reconcile settlements on chain
If you ran a TypeScript Solana facilitator below 2.23.0, compare what it recorded as settled with what arrived in merchant token accounts:
# Show a settlement transaction and its instructions
solana confirm -v <SIGNATURE>
# Show a merchant token account, including any delegate recorded on it
spl-token display <TOKEN_ACCOUNT_ADDRESS>
A "settled" payment whose transaction holds an approval instead of a transfer, or a merchant balance that did not move, is the mark of the first bug. Also review facilitator fee spend for unexplained spikes.
5. Agent wallets and wallet logins
For each agent wallet, list outgoing transfers since deployment and compare amounts and recipients with what the agent was meant to buy. If you run a site that accepts Sign-In with Ethereum, look for sign ins from agent wallets that do not follow the agent's normal pattern, and confirm your server validates the SIWX domain against its configured origin, as the specification requires.
Remediation: step by step
TypeScript and Node.js
- Upgrade every @x402 package to the same current version.
npm install @x402/core@2.28.0 @x402/svm@2.28.0 @x402/evm@2.28.0 \
@x402/extensions@2.28.0 @x402/fetch@2.28.0 @x402/mcp@2.28.0
# Add any other @x402 packages you use (@x402/axios, @x402/express, @x402/hono, @x402/next)
# pnpm and yarn: same package list, same version
pnpm add @x402/core@2.28.0 @x402/svm@2.28.0 @x402/evm@2.28.0 @x402/extensions@2.28.0
yarn add @x402/core@2.28.0 @x402/svm@2.28.0 @x402/evm@2.28.0 @x402/extensions@2.28.0
- Pin transitive copies with
overrides(npm),pnpm.overridesorresolutions(yarn), then rerunnpm ls. - Fix SIWX call sites. Pass the final URL of the 402 response, after redirects, as the third argument to
createSIWxPayload. - Set explicit spend limits for agents. Keep the default cap unless you need more, and raise it per asset with
allowedAssetsrather than switching controls off. - Add a policy in MCP bridges. The x402 MCP documentation recommends
policiesoncreatex402MCPClient, which run after built in spend controls and before the wallet signs. A defensive example:
import { createx402MCPClient } from "@x402/mcp";
import { ExactEvmScheme } from "@x402/evm/exact/client";
const MAX_ATOMIC = 250_000n; // 0.25 of a 6-decimal stablecoin
const ALLOWED_PAY_TO = new Set(["0xYourTrustedMerchant..."]);
const client = createx402MCPClient({
name: "research-agent",
version: "1.0.0",
schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
policies: [
(_version, reqs) =>
reqs.filter(
(r) => BigInt(r.amount ?? "0") <= MAX_ATOMIC && ALLOWED_PAY_TO.has(String(r.payTo))
),
],
maxRequestTimeoutSeconds: 120,
});
- Run your tests. 2.23.0 renamed asset constants, and 2.25.0 made
buildPaymentRequirements()throw when no scheme server is registered. Fix the errors rather than pinning back. - Rebuild, redeploy and confirm the running version inside the image:
docker run --rm --entrypoint node <your-image> -e "console.log(require('@x402/core/package.json').version)"
Solana facilitator operators
- Upgrade
@x402/svmand@x402/coretogether and restart every replica. - Reconcile pre upgrade settlements, as in detection step 4.
- Keep fee payer accounts funded only for expected volume, and confirm the fee payer isolation and compute price limits the SVM scheme specification requires.
- Tell the merchants you serve which version you run and when you upgraded.
Python, Go and agent wallets
- Upgrade:
pip install -U x402(check withpip show x402);go get github.com/x402-foundation/x402/go/v2@latest(check withgo list -m github.com/x402-foundation/x402/go/v2). Configure spend controls explicitly, and confirm from release notes that SIWX client origin binding is in your version. - Give each agent its own small working wallet, topped up on a schedule, so a missing cap is bounded by the balance.
- If an agent ran below 2.23.0 with an automatic signer and SIWX, treat its sessions on sites that accept its wallet login as suspect.
What changed since first reports
- The fixes predate the write-up by two months: npm releases on 18 August, write-up on 22 October. Teams on a monthly upgrade cadence are probably past 2.23.0 but should check pinned and transitive copies.
- No CVE or GitHub advisory had appeared as of 23 October, so advisory based scanners stay quiet.
- The SIWX specification now carries the client origin rule as a MUST, so the fix is part of the protocol, not just one SDK.
- The repository now lives at
x402-foundation/x402. Older links and forks may point to its previous home, so read the current changelogs.
Open questions
- Which of the 25 are which? Only three are described.
- Legacy v1 packages. The researchers say the Solana bug affected v1 and v2 exact schemes in the TypeScript facilitators. The fix landed in
@x402/svm. Whether the separately published legacyx402package (latest 1.2.0, April 2026) carries the flaw is not stated. - Python and Go SIWX client binding. Pull requests are referenced but we could not match them to released versions.
- Hosted facilitators. Their upgrade dates are not public.
- Schema validation on decode. We did not find a changelog entry that clearly addresses the skipped validator.
What would have helped
Each bug is a missing check at a boundary with a well known counterpart in ordinary web and payment security. That makes them good teaching cases for any team building agents that pay.
Practices for teams building agent payments
- Treat every field in a 402 response as hostile input. Amount, token, network, recipient and SIWX domain come from the server. Validate them against your own configuration before signing.
- Make the budget part of the agent's identity. Per payment caps, daily totals and allowed tokens, networks and recipients belong in configuration reviewed like any permission. "Implementation-specific," in the specification's words, means it is your job.
- Bind every signature to an origin you chose. EIP-4361 asks wallets to check origin; an agent SDK is the wallet.
- Check type before content. Confirm what kind of instruction, message or token you hold before trusting its fields.
- Reconcile on chain. "Settled" from a facilitator is a claim; compare it to actual token movements on a schedule.
- Keep lockstep packages in lockstep, with a CI check that fails when @x402 versions differ.
- Do not wait for an advisory. These fixes never got one. Track release notes for security sensitive SDKs and upgrade on a short cadence.
- Keep a human in the loop for anything unusual: a payment above the cap, a new recipient, an unexpected sign in.
Where Safeguard fits
Safeguard does not sit in the payment path. It does not verify x402 payments, watch wallets, inspect Solana transactions or decide whether an agent should sign. Those checks belong in the SDK, the facilitator and your application.
Where it helps is the software that carries the bugs:
- Knowing what you run. SBOM and dependency scanning of repositories, container images and SBOM files (
safeguard scan --dir .,safeguard scan --image <name>,safeguard scan --sbom <file>, with JSON results under./output). The platform shows which projects contain a given component and version, so "which services ship@x402/svmbelow 2.23.0" is a query, including transitive copies inside images. - Matching and ranking. Vulnerability matching against vulnerability databases, with reachability analysis. Honest caveat: matching needs a record, and these findings have none, so a version based policy is the control that catches them.
- Stopping regressions. Policies and gates evaluated in the platform at build, CI and release can fail a build on any @x402 package below 2.28.0.
- Fixing with approval. Autonomous remediation opens fix pull requests and ships switched off, with every category set to Manual. The Safeguard CLI's assistant can edit code and run commands with your approval, which matters here because the upgrade changes the
createSIWxPayloadsignature and renames constants./permissionsoffers Ask, Accept edits, Plan, Auto (the default) and Strict, and the desktop and phone apps can approve each command remotely.
Zero-Day Discovery and Gold
Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, issues findings as SGZ advisories before they reach public CVE databases, and covers seven package ecosystems. We make no claim that it found any of these x402 issues or that an SGZ advisory exists for them; an outside research team found and disclosed them.
Gold Open Source shows known CVEs, fixed versions and a recommended safe version for free, and Gold Registry supplies hardened, signed components and images; both are described below. We do not claim Gold holds a hardened @x402 build or had one before the public fix. The habit that matters is general: pull patched, signed components from a curated source and rebuild fast when a fix lands.
Common mistakes
- Upgrading
@x402/corealone. The Solana guard is in@x402/svmand the SIWX binding in@x402/extensions. - Trusting
npm auditto tell you. There is no advisory for it to match. - Turning off spend controls to make tests pass. Opt specific assets in instead; never set
spendControls: falsein an unattended agent. - Passing the wrong URL to
createSIWxPayload. It must be the final URL of the 402 response, not a hard coded base URL. - Stopping at the minimum fixed version. 2.27.0 fixed a further route bypass. Go to the latest.
- Forgetting the container. A lockfile change does nothing until the image is rebuilt and redeployed.
FAQ
What is x402?
An open standard for paying for web resources inside an HTTP exchange. A server answers 402 Payment Required with payment options, the client signs a payment and retries, and a facilitator verifies and settles it, often on chain. It targets automated clients and AI agents.
Which versions fix the critical bugs?
For TypeScript, 2.23.0 of @x402/svm, @x402/extensions and @x402/core, published on 18 August 2026. We recommend the latest, 2.28.0 at the time of writing, across every @x402 package.
Is there a CVE or GitHub advisory?
We found neither as of 23 October 2026. The repository's two published advisories are older and unrelated, which is why npm audit will not flag these versions.
Was anyone attacked?
The write-up describes local tests and reports no exploitation, and nobody has publicly reported losses. If you ran an affected Solana facilitator, reconcile settlements on chain to confirm it for yourself.
I only run a client. Do I need to upgrade?
Yes. The Solana bug is facilitator side, but the spending limit and SIWX bugs are client side. An agent with an automatic signer and no policy could authorise its whole balance of a supported token.
Does the spend control default break my integration?
It may. From 2.23.0 the default allows only recognised pegged assets with a $1 cap per payment. Opt other tokens or larger amounts in through allowedAssets with a per asset cap.
Does this affect MCP servers that pay for tools?
If the MCP server pays through @x402/mcp, it uses the same client and defaults. Upgrade it and add policies to createx402MCPClient so payments are filtered before the wallet signs.
Are Python and Go clients affected?
Per the TypeScript fix's pull request, Python and Go already checked the Solana instruction type. Both added client spend controls on 18 August. SIWX client binding pull requests are referenced but we could not match them to releases, so upgrade and check the release notes.
Would Safeguard have stopped this?
No. It shows every project and image carrying an affected @x402 version, lets you gate builds on a minimum version, and helps make the upgrade, including the code changes, with approval at each step.
Fix it without waiting for upstream
In this case upstream moved quickly: the critical fixes were released six days after the report. The gap that remains is between that release and your production builds, and with no advisory to trigger alerts, that gap can stay open for months.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would have helped
These are real product sessions on other examples. None of them shows x402, a payment, a wallet or these findings.
The CLI demo shows the assistant fixing a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json, runs install and tests with your approval, and pushes nothing. For x402 you would run safeguard scan --dir . in the agent's repository and ask the assistant to move every @x402 package to the same version and update the createSIWxPayload call sites, approving each step.
Click through it at your own pace, or open it full screen.
The desktop app demo shows a CLI session in the conversation list, a folder choice, and Approve or Deny on each command and file edit, ending with the upgrade done and tests passing. Here you would pick the facilitator or MCP bridge repository and ask for the @x402 upgrade plus explicit spend policies, approving each edit yourself.
Click through it at your own pace, or open it full screen.
The mobile demo shows a real Android session: work is sent to a computer running the CLI, and each command is approved on the phone with Allow once, Allow for turn or Deny. For a Solana facilitator you would send the upgrade and restart to the build machine and approve the steps from your phone: a human decision before anything with consequences runs, which is exactly what the missing spend limit removed.
Click through it at your own pace, or open it full screen.
To try it on your own projects, download Safeguard and read the CLI documentation. Related reading: CERT-In's advisory on AI agent attack vectors, what AI-found bugs like PHP2Shell and PwnEscape mean for defenders, the incident response playbook for a compromised dependency and October 2026 security incidents and what would have helped.
Quick check
Why will npm audit not flag a vulnerable @x402 version for these findings?
There is no CVE or GitHub security advisory for them, so the audit has no record to match. The fixes are documented only in the x402 changelogs and pull requests. Check versions directly with npm ls or npm query and require 2.23.0 or later, ideally the latest release, across every @x402 package.
What must a client check before signing a Sign-In-With-X challenge?
That the challenge's domain and the origin of its uri match the origin of the URL that actually returned the 402 response, after redirects. From 2.23.0 the TypeScript SDK enforces this when you pass that URL as the third argument to createSIWxPayload, and the SIWX specification makes it a MUST.
Sources
- Original research write-up: 25 Vulnerabilities in the x402 Protocol (primary)
- x402 repository README
- x402 protocol specification v2
- x402 Sign-In-With-X extension specification
- x402 exact scheme on Solana (SVM) specification
- @x402/core changelog
- @x402/svm changelog
- @x402/extensions changelog
- @x402/fetch changelog
- @x402/mcp changelog
- @x402/evm changelog
- Python x402 changelog
- Go x402 changelog
- Pull request 3124: spend controls
- Pull request 3132: require TransferChecked discriminator in svm exact
- Pull request 3133: bind SIWX client challenge to the request origin
- x402 security advisories
- GHSA-qr2g-p6q7-w82m (March 2026, unrelated)
- GHSA-3j63-5h8p-gf7c (August 2025, unrelated)
- npm registry: @x402/core
- npm registry: @x402/svm
- npm registry: @x402/extensions
- npm registry: @x402/mcp
- npm registry: x402 (legacy v1 package)
- x402 documentation: MCP Server with x402
- x402 documentation: Facilitator
- Solana documentation: Transfer Tokens
- Solana documentation: Approve Delegate
- EIP-4361: Sign-In with Ethereum
- Safeguard: Skynet LLMjacking Agent: How Exposed AI Models Get Hijacked
Last reviewed: 23 October 2026. This is a developing story; check the linked advisories for the latest status.