T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/clanker.sh:318
- Finding
- Wallet Private Key Exposed Through Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clanker.sh`, lines 318-327; `scripts/deploy.py`, lines 586-607 **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: High ### Vulnerable Code ```bash local private_key=$(get_private_key "$network") if [[ -z "$private_key" ]]; then print_error "Cannot deploy: private key not configured" exit 1 fi local rpc_url=$(get_rpc_url "$network") # Use Python deployment helper python3 "$SCRIPT_DIR/deploy.py" "$network" "$name" "$symbol" "$lp_eth" "$private_key" --rpc-url "$rpc_url" ``` The Python helper explicitly accepts the key as a positional argument: ```python parser.add_argument( "private_key", help="Private key (with or without 0x prefix)" ) args = parser.parse_args() deploy_token( args.network, args.name, args.symbol, args.initial_lp_eth, args.private_key, args.rpc_url, ) ``` ### Technical Analysis The shell script reads the wallet private key from the configuration and inserts it directly into the `python3` process argument vector. On operating systems that expose process arguments through facilities such as `/proc/<pid>/cmdline`, `ps`, process-monitoring agents, audit logs, crash diagnostics, or endpoint telemetry, the complete private key may become visible outside the deployment process. The deployment helper may remain active while waiting up to 120 seconds for a transaction receipt, increasing the observation window. Although `deploy.py` signs transactions locally and transmits only signed transactions to the RPC endpoint, that protection is undermined by exposing the signing key in the local process metadata. Passing the arguments as a quoted array prevents shell command injection, but quoting does not protect the key from process-list disclosure. ### Attack Path 1. A user configures a funded Base wallet and invokes `clanker.sh deploy` or `clanker.sh testnet-deploy`. 2. `clanker.sh` extracts the complet ...[truncated 1355 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove the positional `private_key` argument from `deploy.py`. - Pass the key through a protected anonymous pipe or standard input, ensuring it is never printed or included in error messages. - Prefer a signer abstraction backed by a hardware wallet, operating-system keychain, encrypted keystore, or external signing service. - If an environment variable is used as an interim measure, remove it immediately after reading and recognize that some process-inspection environments may expose environment variables as well. - Avoid storing the complete configuration JSON, including keys, in global shell variables. - Clear shell variables holding secrets as soon as signing is complete. - Add automated tests that inspect the child process command line and verify that no private key is present. - Document that any wallet previously used with this implementation should be considered at risk if untrusted local monitoring or telemetry was present. A safer interface would read the key from standard input: ```bash get_private_key "$network" | python3 "$SCRIPT_DIR/deploy.py" \ "$network" "$name" "$symbol" "$lp_eth" \ --private-key-stdin \ --rpc-url "$rpc_url" ``` The Python process should then read exactly one line from standard input without logging it. ]]>
