T09 · Insecure Skill Coding Practices
Error
- Location
- data/agent.json:2
- Finding
- Bundled Plaintext Signing Key Enables Identity Impersonation<![CDATA[ ## Vulnerability Details **File Location**: `data/agent.json:2-4`; related identity-loading and storage behavior in `lib/cli.js:58-65` and `lib/cli.js:78-89` **Vulnerability Type**: Hardcoded secret and insecure plaintext credential storage **Risk Level**: High ### Vulnerable Code `data/agent.json:2-4`: ```json { "publicKey": "fef67ba4cdd9fe2ac98d9bd77538dc05fe041b606137b30bc62c9f6e1c1db401", "secretKey": "8c2edcdae88b04559bab3027f7bb7ce3527654e85bf99dd124a1a9e374d967cffef67ba4cdd9fe2ac98d9bd77538dc05fe041b606137b30bc62c9f6e1c1db401", "createdAt": "2026-01-31T18:45:31.635Z" } ``` `lib/cli.js:58-65`: ```js if (existsSync(CONFIG_PATH)) { const existing = JSON.parse(readFileSync(CONFIG_PATH, 'utf8')); console.log(` ⚠️ Keypair already exists! Your public key: ${existing.publicKey} Delete ${CONFIG_PATH} first if you want to generate a new one. `); return; } ``` `lib/cli.js:78-89`: ```js const config = { publicKey: keypair.publicKey, secretKey: keypair.secretKey, createdAt: new Date().toISOString() }; writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2)); console.log(` ✨ Star Pulse identity generated! Your public key (ID): ${keypair.publicKey} Config saved to: ${CONFIG_PATH} ⚠️ Keep your secret key safe! `); ``` ### Technical Analysis The distributed project contains a complete plaintext Ed25519 secret key. Possession of this key is sufficient to produce signatures accepted as originating from the associated public identity. The exposure is aggravated by the key-generation logic. If `data/agent.json` already exists, `keygen()` refuses to generate a replacement. Consequently, installations that include the bundled file may continue using the same publicly exposed signing identity unless the operator manually deletes it. The key-storage operation also does not specify a restrictive file mode. It relies on the host's default umask, which can result in newly generated secret keys being readable by other local use ...[truncated 1980 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Immediately revoke, retire, or otherwise stop trusting the exposed public identity. Treat the bundled secret key as permanently compromised. 2. Remove `data/agent.json` from the distributed package and repository. 3. Purge the secret from repository history and any published package versions where feasible. 4. Add `data/agent.json` and other generated credential files to `.gitignore`, `.npmignore`, or the package allowlist configuration. 5. Generate a unique keypair on each installation or first use instead of distributing a default identity. 6. Detect and reject known bundled or default keys during startup and require identity regeneration. 7. Create the credential file atomically with owner-only permissions, for example: ```js writeFileSync( CONFIG_PATH, JSON.stringify(config, null, 2), { mode: 0o600, flag: 'wx' } ); ``` 8. Verify and, where necessary, repair permissions on existing credential files before loading them. 9. Prefer an operating-system credential store, hardware-backed key storage, or encrypted secret storage where available. 10. Document backup, rotation, compromise-recovery, and identity-revocation procedures for users. ]]>
