T09 · Insecure Skill Coding Practices
- Location
src/index.js:409- Finding
Unbounded Server-Directed x402 Wallet Payments
- Content
View full analysis
Vulnerability Details
File Location:
src/index.js, lines 409-422
Vulnerability Type: Missing payment authorization constraints
Risk Level: HighVulnerable Code:
js // Construct the x402 client with the CDP-backed signer. let response; try { const { account } = await loadAccount(); const signer = toX402Signer(account); const client = new x402Client(); registerExactEvmScheme(client, { signer }); const fetchWithPayment = wrapFetchWithPayment(fetch, client); response = await fetchWithPayment(url, { method, headers, ...(body !== undefined ? { body } : {}), });Technical Analysis
The Skill converts the funded CDP account into a signer and gives it directly to an x402 client. The remote endpoint supplies the payment requirements, but the Skill does not locally enforce:
- A maximum payment amount
- A cumulative or daily spending limit
- An allowed chain or network list
- An allowed token or token-contract list
- A recipient or facilitator allowlist
- Interactive approval for unexpected payment terms
The declared
CDP_NETWORKsetting does not constrainpay-x402; therefore, the server can select any EVM network and payment terms supported by the installed x402 client and signer. Relying exclusively on Agent reasoning or optional external CDP policies does not provide a secure default in this implementation.Attack Path
- An attacker causes the Agent to invoke
pay-x402with a malicious or compromised endpoint. - The endpoint returns an HTTP 402 response containing attacker-selected, x402-compatible payment requirements.
wrapFetchWithPaymentprocesses those requirements using the unrestricted CDP-backed signer.- The wallet signs a payment authorization without a local amount, asset, network, or recipient policy check.
- The x402 flow submits the authorization and retries the resource request.
- Funds can be settled acco ...[truncated 652 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the HTTP 402 payment requirements before creating or signing an authorization.
- Enforce an operator-configured maximum amount per payment and a cumulative spending limit.
- Restrict payments to explicit chain IDs, such as Base mainnet and optionally Base Sepolia.
- Validate the requested asset against an allowlist of known USDC contract addresses.
- Add recipient and facilitator allowlists where operationally possible.
- Reject ambiguous, malformed, unsupported, or multi-option requirements unless one option passes every policy check.
- Require explicit operator confirmation when payment terms exceed a configured threshold or do not match a preapproved policy.
- Configure equivalent hard limits in the CDP policy engine as defense in depth.
- Log proposed and approved payment terms without logging credentials or sensitive authorization material.
