T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:6
- Finding
- Automatic Paid Requests Use an Unrestricted EVM Private Key Without Documented Spending Controls## Vulnerability Details **File Location**: `SKILL.md`, lines 6–9, 30–40, and 52–61 **Vulnerability Type**: Automatic payment authorization with insufficient transaction constraints **Risk Level**: Medium The skill requires a wallet private key and directs the agent to pass it to an x402 client that automatically authorizes paid requests. **Relevant code from lines 6–9:** ```yaml requires: env: - EVM_PRIVATE_KEY primaryEnv: EVM_PRIVATE_KEY ``` **Relevant code from lines 30–40:** ```markdown The x402 client handles payment authorisation automatically. No API key, no account, no subscription required — just an EVM wallet with USDC on Base mainnet. ```python # Example using the x402-python client from x402.client import x402_get response = x402_get( url="https://apexrunner.ai/signals/btc-dominance", private_key=os.environ["EVM_PRIVATE_KEY"] ) print(response.json()) ``` ``` **Relevant code from lines 52–61:** ```markdown ## Pricing **$0.15/call** — standard price Early adopters automatically receive 30% off ($0.10/call) until 2026-09-21. Discount tiers apply automatically based on wallet call history: - Early Adopter (0–9 calls): 30% off - Engaged (10–49 calls): 15% off - Loyal (50–199 calls): 15% permanent - VIP (200+ calls): 20% permanent Check your tier: `https://apexrunner.ai/signals/my-pricing` ``` ### Technical Analysis An EVM private key grants transaction-signing authority over its wallet. The documented flow supplies that key directly to a third-party x402 client and states that payment authorization occurs automatically. Although the documentation advertises a per-call price, it does not require the caller to independently enforce or validate: - The maximum payment amount - The Base mainnet chain identifier - The expected USDC token contract - The authorized payment recipient - A per-session or cumulative spending limit - User confirmation before ...[truncated 2477 chars]
- Remediation
- ## Remediation Suggestions 1. Use a dedicated, low-balance payment wallet instead of a primary or general-purpose wallet. 2. Require explicit user confirmation before each paid request, showing the exact amount, token, chain, and recipient. 3. Enforce a local maximum payment amount independent of pricing information returned by the server. 4. Validate the Base mainnet chain ID, canonical USDC contract address, expected recipient, endpoint origin, and transaction calldata before signing. 5. Add per-request, per-session, and daily cumulative spending limits, with fail-closed behavior when any limit is exceeded. 6. Isolate signing in a restricted wallet service or hardware-backed signer so the raw private key is not passed to general agent code or third-party libraries. 7. Pin the x402 dependency to a reviewed version, verify package provenance and integrity, and document the exact package installation source. 8. Prevent automatic retries from producing duplicate charges and maintain an auditable payment log. 9. Correct the example by adding `import os`; this is a functional hardening measure rather than the primary security fix.
