T09 · Insecure Skill Coding Practices
- Location
secrets-inject.js:126- Finding
Plaintext secrets persist in generated temporary shell scripts
- Content
View full analysis
Vulnerability Details
File Location:
secrets-inject.js:126-133
Vulnerability Type: Plaintext secret exposure through persistent temporary files
Risk Level: HighVulnerable Code
javascript const tmpFile = path.join(os.tmpdir(), `secrets-inject-${process.pid}-${Date.now()}.sh`); writeSecure(tmpFile, '#!/bin/sh\n' + result + '\n'); trackTmpInjection(tmpFile, Object.keys(secrets)); console.log(`[secrets-inject] ✅ Injected ${injected} secret(s) into: ${tmpFile}`); console.log(`[secrets-inject] Run with: sh ${tmpFile}`); console.log(`[secrets-inject] File mode 0600. Clear with --cleanup-tmp.`); console.log(`[secrets-inject] ⚠️ This temp file contains PLAINTEXT secrets. Delete it after use.`); return tmpFile;Technical Analysis
The implementation embeds decrypted secret values directly into a shell command and writes the resulting plaintext command to a file under the operating system's shared temporary directory. Although
writeSecureapplies mode0600, file permissions do not protect secrets from other processes running under the same account, backups, snapshots, crash collection, forensic recovery, or subsequent permission and ownership mistakes.The files are not automatically deleted after command execution. Cleanup depends on the user explicitly invoking
--cleanup-tmp, creating an indefinite secret-retention window if cleanup is forgotten or fails.The behavior is prominently disclosed in the documentation and is intentional, but it remains a high-risk secret-handling design because the confidentiality of every substituted credential becomes dependent on temporary-file lifecycle management.
Attack Path
- A user invokes
--injectwith a command containing one or more secret placeholders. - The skill reads the master key and decrypts matching records from the secrets store.
- The decrypted values are inserted directly into the shell command.
- The complete ...[truncated 944 chars]
- A user invokes
- Remediation
View remediation
Remediation Suggestions
- Avoid embedding secrets in command-line text or persistent scripts.
- Prefer passing secrets through protected standard input, inherited file descriptors, or narrowly scoped environment variables when the target program supports them.
- If a file is unavoidable, create a private directory with
fs.mkdtempSync, apply mode0700, and place the secret file inside it. - Execute the generated command through a controlled wrapper and remove the file in a
finallyblock immediately after execution. - Add signal and process-exit handlers as defense-in-depth cleanup measures, while recognizing that they cannot guarantee cleanup after abrupt termination.
- Minimize retention by writing only the secret value required by the target program rather than a complete executable command.
- Document and enforce a maximum lifetime for generated material, and purge stale files automatically during startup.
