T09 · Insecure Skill Coding Practices
- Location
- strategy-scheduler.js:84
- Finding
- Wallet Private-Key Prefix Disclosed in Scheduler Logs<![CDATA[ ## Vulnerability Details **File Location**: `strategy-scheduler.js:84-98` **Vulnerability Type**: Sensitive key material exposure through application logs **Risk Level**: Medium ### Vulnerable Code ```javascript async function startScheduler() { console.log(` ╔═══════════════════════════════════════════════════════════════════╗ ║ DeFi Strategy Scheduler - LIVE ║ ╠═══════════════════════════════════════════════════════════════════╣ ║ Engine: ${deployedConfig.network} ║ Wallet: ${PRIVATE_KEY ? PRIVATE_KEY.slice(0, 10) + '...' : 'Not loaded'} ║ RPC: ${RPC_URL.slice(0, 40)}... ║ Strategies: Compound Yield, Rebalance, Dynamic Harvest ║ ║ Cycle Interval: ${EXECUTION_INTERVAL}s ║ ║ On-Chain Logging: ENABLED ║ ╚═══════════════════════════════════════════════════════════════════╝ `); if (!PRIVATE_KEY) { console.error('❌ PRIVATE_KEY not found in .env'); process.exit(1); } ``` ### Technical Analysis The scheduler prints the first ten characters of `PRIVATE_KEY`. For a conventional Ethereum key beginning with `0x`, this discloses eight hexadecimal key digits, or 32 bits of private-key material. Private keys should be treated as indivisible secrets. Partial disclosure does not by itself make recovery of a properly generated 256-bit key computationally practical, but it unnecessarily reduces its unknown entropy and creates reusable secret material in terminal history, process supervisors, container logs, CI logs, and centralized observability systems. The disclosure is unnecessary because the public wallet address is already derivable by the initialized wallet and provides sufficient operator identification without exposing signing material. ### Attack Path 1. An operator starts `strategy-scheduler.js` with a funded wallet key in `.env`. 2. The scheduler emits the private-key prefix to standard output. 3. A user or service wi ...[truncated 766 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never print any portion, fingerprint, hash, or encoding of a private key. - Replace the output with the public wallet address: ```javascript const walletLabel = engine.wallet?.address || 'Not loaded'; console.log(`Wallet: ${walletLabel}`); ``` - Load secrets through a dedicated secret manager where possible. - Restrict access to process and container logs. - Rotate wallet keys if existing logs containing key prefixes were broadly distributed. - Add automated secret-redaction tests that fail if private-key variables are interpolated into log messages. ]]>
