T09 · Insecure Skill Coding Practices
- Location
SKILL.md:6- Finding
Unrestricted Automated Payments Using a Raw EVM Private Key
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 6–9, 25–35, and 46
Vulnerability Type: Raw private-key exposure to a payment-capable client without documented spending controls
Risk Level: HighVulnerable Code
yaml metadata: openclaw: requires: env: - EVM_PRIVATE_KEY primaryEnv: EVM_PRIVATE_KEYmarkdown The agent makes an x402-authenticated GET request to:https://apexrunner.ai/signals/signal-intelligence
text 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/signal-intelligence", private_key=os.environ["EVM_PRIVATE_KEY"] ) print(response.json())text ```markdown **$0.25/call** — standard priceTechnical Analysis
The skill requires access to a reusable EVM private key and passes that key directly to
x402_get, a third-party client capable of signing payment authorizations. The documentation explicitly states that payment authorization occurs automatically.Although the documented service price is
$0.25/call, the skill does not demonstrate client-side enforcement of that amount. It also provides no explicit per-payment confirmation, maximum transaction amount, cumulative spending budget, request-count limit, recipient allowlist, chain validation, token restriction, or isolated-wallet requirement.Consequently, the signing authority available to the skill is broader than necessary for retrieving one signal. The private key potentially controls every asset and permission associated with the configured wallet, while the intended task only requires narrowly scoped payment authorization. There is no evidence in the reviewed file that the key is deliberately exfi ...[truncated 1507 chars]
- Remediation
View remediation
Remediation Suggestions
- Use a dedicated, low-balance payment wallet rather than a primary wallet or a key controlling unrelated assets.
- Prefer a scoped session key, delegated authorization, or smart-account policy that can only pay the intended recipient, token, network, and maximum amount.
- Validate the x402 payment challenge before signing, including:
- Expected Base mainnet chain identifier
- USDC token contract
- Approved recipient
- Maximum charge per request
- Challenge expiration and nonce
- Enforce a client-side cumulative spending budget and request-count limit that cannot be overridden by remote response data.
- Require explicit user confirmation before each payment, showing the recipient, token, amount, network, and remaining budget.
- Prevent uncontrolled retries and agent loops by making paid calls non-retriable by default or by applying a strict retry ceiling.
- Pin the x402 client to a reviewed version, verify package integrity, and audit its key-handling and payment-validation behavior.
- Ensure the private key is never logged, serialized, included in errors, exposed to unrelated tools, or retained after execution.
- Document wallet isolation and maximum funding requirements directly in the skill instructions.
