T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/wallet_manager.py:30
- Finding
- Plaintext Private-Key Exposure Through Serialization and Console Output## Vulnerability Details **File Location**: `scripts/wallet_manager.py:30-34` **Additional Locations**: `README.md:27-32`, `scripts/wallet_manager.py:94-98`, `examples/basic_usage.py:20-24` **Vulnerability Type**: Plaintext handling and disclosure of wallet private keys **Risk Level**: High ### Vulnerable Code `scripts/wallet_manager.py:30-34`: ```python def to_dict(self) -> Dict: return { "address": self.address, "private_key": self.private_key } ``` `README.md:27-32`: ```python # Create a new wallet wallet = WalletManager.create_wallet() print(f"Address: {wallet.address}") print(f"Private Key: {wallet.private_key}") # Query balance ``` `scripts/wallet_manager.py:94-98`: ```python wallet = WalletManager.create_wallet() print(f"Address: {wallet.address}") print(f"Private Key: {wallet.private_key[:20]}...{wallet.private_key[-10:]}") # Validate address ``` `examples/basic_usage.py:20-24`: ```python print("\n[Step 1] Creating a new Ethereum wallet...") wallet = WalletManager.create_wallet() print(f"✓ Address: {wallet.address}") print(f"✓ Private Key: {wallet.private_key[:20]}...{wallet.private_key[-10:]}") print(" ⚠️ IMPORTANT: Save this private key securely!") ``` ### Technical Analysis `Wallet.to_dict()` places the complete private key into a normal dictionary without encryption, access controls, or an explicit secret-export operation. Such dictionaries can easily be serialized, logged, sent through telemetry, included in exception diagnostics, or persisted in plaintext. The documented quick-start example is more severe because it explicitly prints the complete private key. The executable examples also print private-key fragments. Although those fragments alone do not expose the entire key, they unnecessarily disclose secret material and encourage unsafe handling practices. Private keys are bearer credentials: possession of the full key is su ...[truncated 1452 chars]
- Remediation
- ## Remediation Suggestions 1. Remove `private_key` from the default `to_dict()` output. Default serialization should contain only non-secret wallet metadata such as the public address. 2. Replace generic plaintext export with an explicitly named operation such as `export_encrypted_keystore(password)`. 3. Use the Ethereum encrypted keystore format and a strong, user-supplied password with an appropriate key-derivation function. 4. If encrypted keystores are written to disk, create files with restrictive owner-only permissions and avoid predictable temporary files. 5. Remove all complete and partial private-key output from the README, examples, tests, and command-line demonstrations. 6. Ensure object representations, logs, exceptions, telemetry, and debugging output redact secret values. 7. Add tests that verify private keys are absent from default serialization and console output. 8. Document secure backup procedures and advise users to rotate any wallet whose key may already have entered logs or plaintext storage.
