T09 · Insecure Skill Coding Practices
- Location
SKILL.md:88- Finding
Payment Wrapper Receives Signing Authority Without an Explicit Approval Gate
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 88–116
Vulnerability Type: Missing payment authorization control
Risk Level: HighVulnerable Code
text **No funds are ever auto-debited.** The payment flow is: 1. Agent calls a paid tool (e.g. `create_script`) 2. Server responds with **HTTP 402 Payment Required** containing the exact USDC amount, recipient wallet, and network 3. The agent's x402 client library reads the 402 response and **presents the payment for authorization** — the agent decides whether to sign 4. If the agent authorizes, the client signs a USDC transfer for the exact amount specified and retries the request with the signed payment proof 5. Server verifies the payment, settles the transaction on-chain, and processes the request **Each payment is explicit, per-request, and for an exact amount.** The server cannot withdraw funds, charge more than the stated amount, or initiate payments. The agent (or its x402 client) must actively sign each transaction.typescript import { wrapFetch } from "@x402/fetch"; import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { base } from "viem/chains"; // Create wallet from the dedicated agent wallet key const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY); const wallet = createWalletClient({ account, chain: base, transport: http() }); // Wrap fetch — paid requests are handled via 402 → sign → retry const x402fetch = wrapFetch(fetch, wallet, "eip155:8453");text The wrapped `fetch` handles the 402 challenge-response cycle.Technical Analysis
The example grants the HTTP payment wrapper access to a signing-capable wallet. However, it does not implement or demonstrate a mandatory authorization callback between receiving a server-controlled HTTP 402 challenge and signing the resulting USDC authorization.
This conflicts with the d ...[truncated 1529 chars]
- Remediation
View remediation
Remediation Suggestions
- Require an explicit, non-bypassable approval callback before every signature.
- Present the operation, exact amount, USDC token contract, chain ID, recipient, expiration, and cumulative spend to the approving user or agent.
- Independently parse and validate the HTTP 402 challenge rather than relying exclusively on the remote endpoint or wrapper.
- Allowlist the expected chain, token contract, recipient addresses, and payment protocol version.
- Enforce per-transaction, per-operation, daily, and lifetime spending limits.
- Reject challenges whose payment parameters differ between the initial response and retry.
- Default to denying payments when approval is unavailable, ambiguous, or times out.
- Record tamper-evident payment audit logs without recording the private key or sensitive authorization material.
- Update the example to show the actual approval mechanism instead of asserting that the wrapper presents one.
