T09 · Insecure Skill Coding Practices
Warning
- Location
- rules/wallets.md:39
- Finding
- Automatic Payment Execution Without Transaction-Level Validation or Approval## Vulnerability Details **File Location**: `rules/wallets.md`, lines 39–46 and 65–68 **Vulnerability Type**: Unbounded automatic payment authorization **Risk Level**: Medium ### Vulnerable Code ```markdown ### Making a paid request `tempo request` handles the 402 challenge and payment automatically: ```bash tempo request -t -X POST \ -H "Content-Type: application/json" \ --json '{"query":"query { getNetworks { id name } }"}' \ https://graph.codex.io/graphql ``` ``` ```markdown ## Rules - **Never print, log, or read private keys.** Tools handle key management internally. - **Always run a preflight check** before attempting paid requests. - **If auth fails, fix it automatically** — run `tempo wallet login` as appropriate, then retry. - **Do not mix tools.** Use tempo for Tempo challenges. ``` ### Technical Analysis The skill instructs the agent to use `tempo request`, which automatically handles the HTTP 402 challenge, signs a payment transaction, and retries the request. Its required preflight check verifies only that the wallet is ready and has sufficient available funds. No instruction requires the agent to inspect or validate the challenge's exact charge, recipient, asset, or other transaction parameters. The skill also defines no per-request or cumulative spending limit and does not require explicit user confirmation before payment. Automatically restoring authentication and retrying can therefore proceed directly into a paid operation without renewed transaction-level authorization. A wallet balance check establishes the ability to pay, not the user's consent to a particular payment. Consequently, an unexpectedly expensive, malformed, or compromised challenge could trigger spending outside the user's intent. ### Attack Path 1. The agent submits an unpaid GraphQL query to begin the MPP flow. 2. The remote endpoint, or a compromised service in that flow, returns a payment challenge containing an excessive or otherwise unintended charge. 3. ...[truncated 932 chars]
- Remediation
- ## Remediation Suggestions 1. Parse the payment challenge before signing and validate: - Network and chain identifier - Recipient or payment destination - Asset and currency - Exact charge and maximum possible charge - Challenge expiration and request binding 2. Allow only explicitly trusted networks, recipients, assets, and service endpoints. 3. Define enforceable per-request and cumulative session spending caps. 4. Display the validated transaction terms and require explicit user confirmation before payment unless the user has already approved a narrowly bounded budget. 5. Treat authentication restoration separately from payment authorization. After `tempo wallet login`, require renewed approval before retrying any paid request. 6. Reject malformed, unsupported, expired, replayed, or unexpectedly priced challenges. 7. Record non-sensitive payment metadata for accountability while continuing to prohibit logging credentials, proofs, or private keys.
