T09 · Insecure Skill Coding Practices
- Location
src/cli.ts:88- Finding
Shell Command Injection Through User-Controlled CLI Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
PayClaw is a coherent payments skill, but it has high-impact safety issues in command execution, credential handling, and misleading escrow behavior that users should review before installing.
Review this carefully before installing. Treat the escrow feature as local bookkeeping, not as real locked or trustless escrow. Do not use it for paid work unless the implementation is changed to lock funds and verify releases/refunds. Avoid entering real payment credentials until command execution is hardened and secret storage is improved; use testnet-only credentials and manually verify every destination and amount.
src/cli.ts:88Shell Command Injection Through User-Controlled CLI Arguments
src/cli.ts:274Advertised Escrow Does Not Lock Funds or Enforce Release Conditions
src/cli.ts:40Predictable Escrow Identifiers and Insufficient Protection of Financial State Files
The escrow feature is presented as if it holds or locks funds, but creation only writes a local JSON record and does not transfer assets into any escrow account or smart contract. In a payments skill, this is dangerous because users or agents may rely on a false trust model and deliver goods/services without any funds actually being secured.
The refund command claims to refund the sender, but it only updates local status to 'refunded' and performs no payment action. This can mislead users into believing funds were returned, causing financial disputes or loss when the payment workflow is used as part of agent-to-agent transactions.
The helper wraps user-influenced strings into execSync(circle-wallet ${cmd}), which invokes a shell. Multiple commands pass unsanitized CLI inputs into cmd such as API keys, wallet names, addresses, and amounts, so an attacker can inject shell metacharacters and execute arbitrary OS commands under the user's account. In a payments skill, this is especially dangerous because it runs in a high-trust financial workflow and can lead to wallet theft, secret exfiltration, or host compromise.
The escrow create flow only writes a local JSON record and never transfers funds into an escrow account or smart contract. Users are told an escrow was created, but no assets are locked, so the feature provides a false security guarantee and can cause counterparties to act on nonexistent payment assurances. In a payment/agent-deal context, misleading escrow semantics materially increase fraud and dispute risk.
The refund command marks an escrow as refunded in local storage and prints success, but performs no blockchain or wallet transfer. This can mislead users into believing funds were returned when no payment happened, potentially causing financial loss, incorrect accounting, and abuse in agent-to-agent transactions. Because the tool presents itself as handling money, false completion messages are especially risky.
The skill exposes payment, wallet, escrow, and setup capabilities but does not declare any explicit tool scope or permissions despite requiring environment/credential access. In an agent ecosystem, missing scope boundaries can cause the host or user to grant broader capabilities than intended, increasing the chance of credential exposure or unauthorized financial actions.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
---
name: payclaw
version: 1.0.0
description: "Agent-to-Agent USDC payments. Create wallets, send/receive payments, escrow between agents. Built for the USDC Hackathon on Moltbook."
metadata: {"openclaw": {"emoji": "💸", "homepage": "https://github.com/rojasjuniore/payclaw"}}
---
The setup instructions ask the user to provide a Circle API key but do not warn about secure handling, storage, rotation, or the risk of exposing credentials through shell history or logs. Because this skill controls wallets and payments, leaked credentials could enable unauthorized wallet management or fraudulent transactions.
The skill documents commands for sending payments and releasing escrow without a prominent warning that these actions may be irreversible and transfer funds. In a payment-focused skill, lack of explicit confirmation and risk messaging materially raises the chance of mistaken or socially engineered fund transfers.
The wrapper executes execSync with a shell command string built from user-controlled input, and multiple call sites pass unsanitized values such as API keys, wallet names, addresses, and amounts into that string. This enables shell injection, allowing arbitrary command execution on the host running the CLI.
The API key is supplied as a CLI argument and then stored locally in config.json, which exposes it to shell history, process listings, and local file compromise. In a wallet/payment tool, credential exposure is especially sensitive because the key may enable unauthorized wallet operations or access to financial infrastructure.
The setup flow persists the Circle API key to a local JSON config file. Although file mode 0600 helps, storing long-lived payment credentials in plaintext without clear disclosure or stronger secret handling increases the risk of compromise from local malware, backups, accidental exposure, or multi-user environments. In a financial skill, API credentials are highly sensitive and deserve stronger protection.
The manifest description advertises both send and receive payments, but this file contains no mechanism to detect, accept, or process inbound payments from the network or wallet provider. The 'request' command only prints instructions, and 'history' displays local records rather than actual received transactions.
This is a manifest file, so vague-trigger checks apply. The description "Agent-to-Agent USDC Payments for OpenClaw" states a general capability but does not define specific activation conditions, scope constraints, or exclusion cases, which can make invocation criteria ambiguous in systems that rely on manifest metadata.
Using a caret range for the runtime dependency allows newer upstream versions to be installed automatically, which can introduce supply-chain risk, unexpected behavior changes, or malicious code if the dependency is compromised. Because this skill handles agent-to-agent USDC payments, dependency integrity matters more than in a non-financial tool.
"author": "IntechChain",
"license": "MIT",
"dependencies": {
"commander": "^12.1.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"commander": "^12.1.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
}
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
}
}
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
}
}
After sending a payment, the code records recipient address, amount, memo, and timestamp into a local history.json file. This is a write of potentially sensitive financial metadata, but the command does not warn the user that transaction details will be stored locally.
The register command stores agent identity metadata, including wallet address and optional description, in a local agents.json file. The command does not disclose that this information will be written to disk, which may matter for privacy-sensitive users.
Detected: suspicious.dangerous_exec