T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/fadnote.js:31
- Finding
- Sensitive note content exposed through command-line arguments and shell history<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fadnote.js:31-55`; insecure usage is documented in `SKILL.md:54` and `SKILL.md:75-76` **Vulnerability Type**: Sensitive information exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```js function parseArgs() { const args = process.argv.slice(2); const options = { ttl: 86400, json: false, content: '', help: false }; const contentArgs = []; for (let i = 0; i < args.length; i++) { if (args[i] === '-h' || args[i] === '--help') { options.help = true; } else if (args[i] === '--ttl' && i + 1 < args.length) { const ttl = parseInt(args[i + 1], 10); if (isNaN(ttl) || ttl <= 0) { throw new Error('Invalid TTL: must be a positive number'); } options.ttl = ttl; i++; } else if (args[i] === '--json') { options.json = true; } else { contentArgs.push(args[i]); } } options.content = contentArgs.join(' '); return options; } ``` The affected interface is explicitly promoted with sensitive-data examples: ```bash fadnote "My secret message" fadnote --ttl 3600 "Expires in 1 hour" ``` The documentation also encourages using the Skill for API keys, passwords, credentials, and private SSH keys. ### Technical Analysis The program accepts note plaintext directly from `process.argv`. Command-line arguments are not an appropriate transport for secrets because they can be exposed outside the application's encryption boundary before client-side encryption occurs. Depending on the operating system and host configuration, the argument vector may be observable through process inspection facilities, process-monitoring software, audit systems, telemetry agents, crash diagnostics, or automation logs. Commands entered interactively can also remain in persistent shell history. The subsequent AES-256-GCM encryption does not protect these earlier plaintext copies. This behavior is not required for the declared fun ...[truncated 1560 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove positional plaintext input for secrets, or disable it by default and require an explicit unsafe compatibility flag. 2. Make stdin the primary non-interactive input mechanism: ```bash printf '%s' "$SECRET" | fadnote ``` This prevents the secret from appearing in the FadNote process argument vector, although callers must still avoid embedding literal secrets in the shell command itself. 3. Add a hidden interactive input mode using a terminal interface that disables input echo. Do not implement secret prompting with ordinary `readline` input unless terminal echo is securely suppressed. 4. Update `SKILL.md` to remove examples that place secrets directly in command-line arguments. Clearly warn that command-line literals can be retained in shell history, process listings, telemetry, and automation logs. 5. For automation, recommend passing content through stdin from a protected secret source without expanding the secret into a logged command line. 6. Add tests verifying that secret content is accepted through stdin and is not present in `process.argv`. 7. Consider rejecting positional content with a clear message directing users to stdin or secure interactive entry. ]]>
