T09 · Insecure Skill Coding Practices
- Location
scripts/shared/storage/base.js:8- Finding
Plaintext Private Keys Are Stored Without Enforced Restrictive Permissions
- Content
View full analysis
entry.alias === args.alias); if (index >= 0) { keys[index].privateKeyHex = args.key; } else { keys.push({ alias: args.alias, privateKeyHex: args.key }); } await this.writeFile(keys); } ``` ### Technical Analysis The key store serializes private keys directly into JSON as `privateKeyHex`. The shared storage implementation creates the `$HOME/.openclaw/billions` directory and its files without explicitly setting restrictive permission modes. Consequently, the actual permissions depend on the process umask and any pre-existing directory permissions. On a multi-user host or in an environment with an unsafe umask, `kms.json` or the temporary `kms.json.tmp` file may be readable by other local principals. The temporary file contains the same plaintext secrets as the final file. Renaming it does not correct its access mode because the renamed file retains the temporary file's permissions. The Skill documentation confirms that `kms.json` contains unencrypted private keys, making this a security boundary rather than ordinary application data. ### Attack Path 1. A user executes `createNewEthereumIdentity.js`, causing a pri ...[truncated 1315 chars]- Remediation
View remediation
