T09 · Insecure Skill Coding Practices
- Location
SKILL.md:18- Finding
Shell Command Injection Through Unescaped Sub-Agent Task Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:18-22andSKILL.md:58-61
Vulnerability Type: Shell command injection caused by unsafe string interpolation
Risk Level: HighVulnerable 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 Practicesbecause the exploitable condition arises from an insecure command invocation pattern documented by the Skill.Attack Path
- An attacker places crafted content in task input or repository material that the orchestrator will include in a sub-agent task.
- The crafted text contains a single quote that closes the command's quoted task argument, followed by shell syntax an ...[truncated 1224 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not construct executable shell command strings by concatenating or interpolating task text.
- Invoke the selected coding-agent executable through an argument-array API that bypasses shell parsing, such as an equivalent of
execFile(agentExecutable, [task]). - Prefer passing large or untrusted tasks through standard input or a securely created task file. Pass only the file path as a discrete argument.
- If shell invocation is unavoidable, use a proven platform-specific escaping library rather than manually adding quotes. Apply escaping to every dynamic argument.
- Treat repository content, user prompts, filenames, issue text, and generated task descriptions as untrusted input.
- 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.
- Run sub-agents with least privilege, a restricted environment, minimal credentials, and an isolated working directory where practical.
- 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.
- Update all foreground and background examples so they demonstrate a non-shell invocation method rather than
command:"AGENT_CMD '...'".
