T09 · Insecure Skill Coding Practices
Error
- Location
- README.md:49
- Finding
- Private Key Exposure Through Incorrect Command-Line Documentation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:49-52`, `README.md:102-105` **Vulnerability Type**: Private key exposure through process arguments and shell history **Risk Level**: High ### Vulnerable Code ```markdown ### CLI Usage ```bash # Initialize wallet arkade init <private-key-hex> ``` ``` The command table repeats the unsafe interface: ```markdown | `init <key> [url]` | Initialize wallet | ``` The actual implementation interprets the first argument as a server URL rather than a private key: ```javascript async function cmdInit(serverUrl) { const existing = loadConfig(); if (existing) { const { sdk } = await getSDK(); const { Wallet, SingleKey } = sdk; const wallet = await Wallet.create({ identity: SingleKey.fromHex(existing.privateKey), arkServerUrl: existing.serverUrl || DEFAULT_SERVER, }); const address = await wallet.getAddress(); console.log("Wallet already initialized."); console.log(`Server: ${existing.serverUrl || DEFAULT_SERVER}`); console.log(`Address: ${address}`); return; } try { const config = await autoInit(serverUrl); ``` ### Technical Analysis The README explicitly directs users to place a Bitcoin private key in a command-line argument. Command-line secrets can be exposed through: - Shell history files - Process listings and process-monitoring utilities - Terminal session recording - CI/CD logs - Agent transcripts and tool-call logs - Audit and telemetry systems The implementation makes the issue more dangerous because `cmdInit` does not import the supplied private key. It treats the argument as `serverUrl` and independently generates a new wallet through `autoInit`. A user may consequently disclose an existing wallet key while unknowingly initializing a different wallet. This violates secure secret-entry principles: cryptographic credentials must not be accepted or requested through process arguments. ### Attack Path 1. A user follows the README ...[truncated 1210 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace every documented invocation with the actual interface: ```bash arkade init [server-url] ``` 2. Change the command table to: ```markdown | `init [url]` | Generate and initialize a new wallet | ``` 3. Add an explicit warning that private keys and mnemonics must never be supplied through command-line arguments. 4. If wallet import functionality is required, implement a separate command such as `arkade import` that reads the key from: - An interactive, non-echoing prompt - Protected standard input - A user-owned file verified to have restrictive permissions 5. Never print an imported key or include it in exception messages, telemetry, or debug logs. 6. Add automated documentation tests that compare documented CLI syntax with the actual command parser. 7. Consider detecting a 64-character hexadecimal first argument to `init` and aborting with a warning, without echoing the supplied value. ]]>
