T09 · Insecure Skill Coding Practices
- Location
- db.js:11
- Finding
- Plaintext Nostr Private Key Stored Without Explicit Filesystem Protection## Vulnerability Details **File Location**: `db.js:11-14`; `identity.js:17-24` **Vulnerability Type**: Plaintext sensitive-data storage with insufficient permission enforcement **Risk Level**: High ### Vulnerable Code ```js const DATA_DIR = path.join(os.homedir(), '.ocmesh'); fs.mkdirSync(DATA_DIR, { recursive: true }); const db = new DatabaseSync(path.join(DATA_DIR, 'ocmesh.db')); ``` ```js // First run — generate fresh keypair const sk = generatePrivateKey(); // returns hex string const pk = getPublicKey(sk); db.prepare('INSERT INTO identity (sk, pk) VALUES (?, ?)').run(sk, pk); ``` ### Technical Analysis The agent's long-lived Nostr private key is stored as plaintext in the `identity.sk` column of `~/.ocmesh/ocmesh.db`. The code does not explicitly create the data directory with mode `0700` or the database with mode `0600`. Its effective accessibility therefore depends on the user's umask and any preexisting permissions on `~/.ocmesh`. The key is the root credential for the agent's identity. Possession of it permits signing events as the agent and decrypting NIP-04 messages available to the attacker. SQLite encryption is not enabled, and no operating-system credential store is used. ### Attack Path 1. An attacker gains local code execution or filesystem read access under another account or compromised process. 2. The attacker checks whether `~/.ocmesh` or `~/.ocmesh/ocmesh.db` is accessible because of permissive inherited permissions or umask settings. 3. The attacker opens the database and executes an equivalent of `SELECT sk FROM identity LIMIT 1`. 4. The extracted key is imported into a Nostr client. 5. The attacker signs messages as the agent, impersonates it to peers, or decrypts captured NIP-04 traffic associated with that key. ### Impact Assessment Successful exploitation compromises the complete cryptographic identity of the ocmesh agent. The attacker can impersonate the agent across the ...[truncated 189 chars]
- Remediation
- ## Remediation Suggestions - Create `~/.ocmesh` with an explicit mode of `0700`. - Set the database and configuration files to mode `0600` immediately after creation and verify their permissions on every startup. - Refuse to start, or display a prominent warning, if the directory or database is readable by group or other users. - Prefer storing the private key in macOS Keychain or another operating-system credential store and retain only a key reference in SQLite. - Provide a supported key-rotation procedure for installations that may already have exposed keys. - Avoid logging or returning the private key through diagnostics, errors, or API responses.
