T09 · Insecure Skill Coding Practices
- Location
SKILL.md:42- Finding
Shell Command Injection Through Unsafe JSON Interpolation
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 42–44
Vulnerability Type: Shell command injection
Risk Level: HighVulnerable Code:
bash echo '<plan json>' | python3 scripts/action_preview.py - # after the user approves the risky ones: echo '<plan json>' | python3 scripts/action_preview.py - --allow-highTechnical Analysis
The Skill directs the Agent to place generated plan JSON inside a single-quoted shell argument. The plan can contain content derived from recommendations, action arguments, issue descriptions, messages, or other potentially untrusted input.
A single quote within that content terminates the shell quoting context. Subsequent shell metacharacters can then be interpreted as commands rather than JSON data. The documented approval mechanism does not mitigate this issue because injection may occur while running either the initial preview command or the approved command.
The helper scripts referenced by these commands are not included in the audited project, so their behavior could not be verified. However, validation inside
action_preview.pywould occur too late to prevent this vulnerability: the shell parses and executes injected syntax before the Python process receives its standard input.Attack Path
- An attacker supplies a recommendation or action field containing a single quote followed by shell syntax.
- The Agent includes that content in the generated plan JSON.
- The Agent directly substitutes the JSON for the
<plan json>placeholder in the documented command. - The attacker's single quote closes the intended quoting context.
- The shell interprets the remaining content as commands before invoking
action_preview.py.
For example, a malicious field shaped like the following could demonstrate execution by creating a file:
text x'; touch /tmp/action_runner_injected; echo 'If directly interpolated into the docume ...[truncated 851 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not interpolate generated JSON into shell command text.
- Invoke Python directly without a shell and provide the serialized JSON through standard input using a process API with an argument array.
- Alternatively, write the plan using a secure temporary file API, set restrictive permissions, and pass the resulting file path as a discrete argument.
- If a shell example must be retained, use a quoted here-document whose delimiter cannot be influenced by input, while documenting that programmatic process invocation is preferred.
- Serialize plans with a standard JSON library rather than manually constructing JSON.
- Treat every recommendation and action field as untrusted, including repository content, issue text, PRD content, Slack messages, and generated descriptions.
- Add regression tests containing single quotes, command substitutions, newlines, backticks, and shell metacharacters.
- Ensure that preview and approval enforcement occurs before any outbound action, but do not rely on application-level validation to address shell parsing vulnerabilities.
