T09 · Insecure Skill Coding Practices
- Location
SKILL.md:16- Finding
Shell Command Injection Through Unescaped Task Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 16–21 and 60–62
Vulnerability Type: Shell command injection
Risk Level: MediumVulnerable Code
markdown | Agent | Invoke Command | |-------|---------------| | Claude Code | `claude '<task>'` | | OpenAI Codex | `codex '<task>'` | | Cursor Agent | `cursor-agent '<task>'` | | Gemini Code | `gemini-code '<task>'` | | Any other | `your-agent-cmd '<task>'` |markdown | 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 documented execution pattern places task content directly inside a shell command delimited by single quotes. It does not require shell-safe escaping, an argument-array API, input validation, or transport through standard input.
If the execution tool passes the resulting command string to a shell, a task containing a single quote can terminate the intended argument. Additional shell operators and commands can then be interpreted as executable syntax rather than task data.
For example, interpolating a task shaped like the following into the documented pattern would break the quoting boundary:
text ' ; attacker-command ; #The resulting command would be structurally equivalent to:
sh AGENT_CMD '' ; attacker-command ; #'Whether exploitation succeeds depends on the surrounding execution API using shell interpretation and on attacker influence over the interpolated task text. The unsafe pattern nevertheless creates a command-injection boundary.
Attack Path
- An attacker influences task text supplied to the orchestration workflow, such as through a repository issue, document, dataset entry, or other untrusted task source.
- The task contains a single quote followed by shell control operators and an attacker-selected command.
- The orchestrator substitu ...[truncated 1054 chars]
- Remediation
View remediation
Remediation Suggestions
-
Do not concatenate task text into a shell command string.
-
Prefer an execution API that accepts the executable and arguments as an array and does not invoke a shell, for example conceptually:
text executable: AGENT_CMD arguments: [task] shell: false -
For lengthy or untrusted tasks, write the task to a securely created temporary file and pass only that file path to the agent.
-
Alternatively, pass task content through standard input when supported by the selected CLI agent.
-
If shell execution is unavoidable, use a well-tested, platform-specific argument-escaping routine rather than manual quote wrapping.
-
Validate task inputs and reject control characters or shell metacharacters where they are not legitimately required.
-
Update all invoke-command examples and foreground/background execution templates to demonstrate shell-free execution.
-
Run delegated agents with least privilege, restricted filesystem access, minimal environment variables, and constrained network access to reduce the impact of any future injection flaw.
-
Add acceptance tests containing single quotes, command substitutions, semicolons, newlines, and shell operators to confirm that task content is passed strictly as data.
-
