T09 · Insecure Skill Coding Practices
- Location
scripts/save_api_key.py:28- Finding
API Key Persisted in Plaintext Shell Startup Files by Default
- Content
View full analysis
Path: shell = os.environ.get("SHELL", "") home = Path.home() if shell.endswith("zsh"): target = home / ".zshrc" elif shell.endswith("fish"): target = home / ".config" / "fish" / "config.fish" line = f"set -gx {ENV_NAME} {shell_quote_single(api_key)}" upsert_line(target, f"set -gx {ENV_NAME}", line) return target else: target = home / ".bashrc" line = f"export {ENV_NAME}={shell_quote_single(api_key)}" upsert_line(target, f"export {ENV_NAME}=", line) return target ``` The documented workflow in `SKILL.md:58-59` instructs the Agent to persist a user-provided key through this script: ```markdown 4. 校验 API Key:优先读取 `SHIYUN_API_KEY`。 5. 用户直接提供 API Key 时,运行 `scripts/save_api_key.py --api-key-stdin` 持久化;通过 stdin 传入,不写入文档、日志或 memory。 ``` ### Technical Analysis Although standard input prevents the key from appearing in command-line history, the default `user` scope writes the unencrypted API key into a shell startup file. These files may be included in backups, diagnostic archives, home-directory synchronization, or accidental disclosures. The implementation does not explicitly enforce owner-only permissions. When an existing startup file has permissive permissions, the key inherits that exposure. When a new file is created, its permissions depend on the process umask rather than a security policy. Persistent storage is not required for an individual image-generation or image-editing reques ...[truncated 1077 chars]- Remediation
View remediation
