T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/send_envelope.ts:525
- Finding
- Nota Sign private key is stored without enforced restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/send_envelope.ts:474-475, 525-526` **Vulnerability Type**: Insecure secret input and storage **Risk Level**: High ### Complete Code Snippet ```typescript console.log('App Key (Base64 encoded PKCS#8 private key):'); const appKey = await prompt('> '); if (!appKey) { return { success: false, message: 'App Key is required' }; } ``` ```typescript // Write config file try { await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf8'); return { success: true, message: 'Configuration saved successfully', configPath }; } catch (error) { return { success: false, message: `Failed to write config file: ${error}` }; } ``` The configuration object written here contains `appId`, `appKey`, `userCode`, `serverRegion`, and `environment`. The `appKey` is a Base64-encoded PKCS#8 RSA private key. ### Technical Analysis The script writes a long-lived authentication private key to a plaintext JSON file without explicitly applying a restrictive file mode. The resulting permissions depend on the process umask and any permissions on an existing file. Under a permissive environment, another local account could read the key. The README recommends manually running `chmod 600`, but the initialization implementation does not enforce this control. The private key is also collected through the ordinary `prompt` function, which reads from standard input without disabling terminal echo. Consequently, the key can be exposed on screen, in terminal recordings, or to shoulder surfing. The private key must remain locally available because it is required to sign JWT and API requests. Persisting it is therefore related to the declared functionality, but storing it without enforced access controls exceeds safe minimum-secret-handling requirements. ### Attack Path 1. A user runs `scripts/send_envelope.ts init`. 2. The user enters the Nota Sign PKCS#8 private key into an echoed terminal prompt. 3. The ...[truncated 1112 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Create `~/.notasign` with mode `0700`. 2. Create the configuration file atomically with mode `0600`, for example by using an exclusive temporary file in the destination directory, applying `chmod`, and then renaming it. 3. Explicitly call `chmod(configPath, 0o600)` after writing, including when replacing an existing file. 4. Before loading an existing configuration, inspect its owner and permission bits. Reject or repair files accessible by group or other users. 5. Disable terminal echo while collecting the private key, and restore terminal state in a `finally` block. 6. Prefer an operating-system credential store or secrets manager over a plaintext JSON file where available. 7. Never include the private key in logs, returned result objects, exception details, or command-line arguments. ]]>
