T09 · Insecure Skill Coding Practices
- Location
references/deployment.md:9- Finding
Blockchain signing secrets are passed through command-line arguments
- Content
View full analysis
Vulnerability Details
File Location:
references/deployment.md:9-31; additional instances inSKILL.md:127-130andreferences/cast-advanced.md:85-112
Vulnerability Type: Sensitive information exposure through process arguments
Risk Level: MediumVulnerable Code
bash # Deploy with constructor args forge create src/Token.sol:Token \ --rpc-url sepolia \ --private-key $PRIVATE_KEY \ --constructor-args "MyToken" "MTK" 18 # Deploy and verify forge create src/Token.sol:Token \ --rpc-url sepolia \ --private-key $PRIVATE_KEY \ --broadcast \ --verify \ --etherscan-api-key $ETHERSCAN_API_KEY \ --constructor-args "MyToken" "MTK" 18 # Deploy with value (payable constructor) forge create src/Vault.sol:Vault \ --rpc-url sepolia \ --private-key $PRIVATE_KEY \ --value 1etherRelated wallet-management examples expose literal private keys or mnemonic phrases in arguments:
bash # Derive from mnemonic cast wallet derive-private-key "word1 word2 ... word12" # Get address from private key cast wallet address --private-key 0x... # Get address from mnemonic cast wallet address --mnemonic "word1 word2..." # Sign message cast wallet sign "message" --private-key 0x... # Import to keystore cast wallet import my-wallet --private-key 0x...Technical Analysis
Private keys and mnemonic phrases are bearer credentials that provide direct control over blockchain accounts. Supplying them as command-line arguments can expose their expanded values through operating-system process inspection, shell history when literal values are used, terminal recording, debugging output, CI diagnostics, or endpoint-monitoring software.
Although
$PRIVATE_KEYis read from an environment variable in several examples, the shell expands it before launchingforge; the resulting private key is therefore included in the child process's argum ...[truncated 1686 chars]- Remediation
View remediation
Remediation Suggestions
- Remove examples that pass private keys or mnemonic phrases through command-line arguments.
- Prefer encrypted Foundry keystores with
--account, hardware wallets through--ledgeror--trezor, or interactive secret entry that does not place the secret in the argument vector. - Document secure keystore creation and explicitly instruct users not to enter funded private keys or mnemonic phrases directly into commands.
- Use dedicated, least-privileged deployment accounts rather than treasury or protocol-administrator wallets.
- Require transaction simulation, chain-ID validation, destination verification, and human approval before production broadcasts.
- In CI, use an isolated signer, hardware-backed key-management service, or short-lived signing service rather than exposing a raw private key to the runner.
- Disable shell tracing around sensitive operations and ensure logs, histories, and deployment artifacts do not contain signing material.
- Retain throwaway keys exclusively for local and testnet examples, and label every example accordingly.
