T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:18
- Finding
- Shell Command Injection Through Unescaped Sub-Agent Task Interpolation## Vulnerability Details **File Location**: `SKILL.md:18-22` and `SKILL.md:58-61` **Vulnerability Type**: Shell command injection caused by unsafe string interpolation **Risk Level**: High ### Vulnerable Code `SKILL.md:18-22`: ```text | Claude Code | `claude '<task>'` | | OpenAI Codex | `codex '<task>'` | | Cursor Agent | `cursor-agent '<task>'` | | Gemini Code | `gemini-code '<task>'` | | Any other | `your-agent-cmd '<task>'` | ``` `SKILL.md:58-61`: ```text | Duration | Mechanism | |----------|-----------| | < 5 min | Foreground: `exec pty:true command:"AGENT_CMD '...'"` | | 5–30 min | Background: `exec pty:true background:true timeout:1800 command:"AGENT_CMD '...'"` | ``` ### Technical Analysis The Skill recommends constructing shell command strings by placing generated task text inside single quotes. Single quotes are not a safe sanitization mechanism when the interpolated task can itself contain a single quote. Such a character terminates the quoted argument, after which shell operators or additional commands can be parsed by the shell. The documentation does not require an argument-array API, safe stdin transport, temporary task files, input validation, or platform-appropriate shell escaping. Task content may incorporate user prompts, repository text, filenames, issue descriptions, or other attacker-controlled context. Consequently, the vulnerable command-construction pattern can turn untrusted task text into executable shell syntax. This is classified as `T09: Insecure Skill Coding Practices` because the exploitable condition arises from an insecure command invocation pattern documented by the Skill. ### Attack Path 1. An attacker places crafted content in task input or repository material that the orchestrator will include in a sub-agent task. 2. The crafted text contains a single quote that closes the command's quoted task argument, followed by shell syntax an ...[truncated 1224 chars]
- Remediation
- ## Remediation Suggestions 1. Do not construct executable shell command strings by concatenating or interpolating task text. 2. Invoke the selected coding-agent executable through an argument-array API that bypasses shell parsing, such as an equivalent of `execFile(agentExecutable, [task])`. 3. Prefer passing large or untrusted tasks through standard input or a securely created task file. Pass only the file path as a discrete argument. 4. If shell invocation is unavoidable, use a proven platform-specific escaping library rather than manually adding quotes. Apply escaping to every dynamic argument. 5. Treat repository content, user prompts, filenames, issue text, and generated task descriptions as untrusted input. 6. Use a fixed allowlist that maps supported agent names to trusted executable paths. Do not allow task content to control the executable or execution options. 7. Run sub-agents with least privilege, a restricted environment, minimal credentials, and an isolated working directory where practical. 8. Add acceptance tests containing single quotes, command separators, substitutions, newlines, and redirection characters to verify that the entire task remains one literal argument and no secondary command executes. 9. Update all foreground and background examples so they demonstrate a non-shell invocation method rather than `command:"AGENT_CMD '...'"`.
