T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:108
- Finding
- Shell Command Injection Through Direct Interpolation of the User's Legal Query<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 108-117 **Vulnerability Type**: Shell command injection through untrusted argument interpolation **Risk Level**: High ### Vulnerable Code The placeholder below is translated to English from the original documentation while preserving the command structure: ```bash python3 ~/.cue/cue-skills/cue-research/scripts/research_run.py \ --query "<USER_QUESTION_VERBATIM>" \ --template-id <RUNTIME_TEMPLATE_ID> \ --output ~/cue-reports/$(date +%Y-%m-%d-%H%M)-legal-practice-cases.md ``` The parameter documentation additionally requires the user's original question to be used without rewriting it. ### Technical Analysis The Skill instructs the Agent to interpolate unmodified, user-controlled text into a double-quoted shell argument. Double quotes do not neutralize all shell metacharacters. In particular, command substitution using `$(...)` or backticks remains active inside double quotes. An embedded quote may also terminate the intended argument and introduce shell operators. For example, if an Agent constructs the documented command through textual substitution, a query containing command substitution could cause the shell to execute the substituted command before Python receives the `--query` argument. This behavior is unnecessary for the declared legal-research functionality. The question only needs to be passed as a data argument to the Python process; it does not need to be interpreted by a shell. ### Attack Path 1. An attacker supplies a purported legal question containing shell syntax such as command substitution or a quote followed by shell operators. 2. The Agent follows the instruction to use the user's question verbatim. 3. The Agent inserts the malicious text into the documented shell command. 4. A shell parses the resulting command line. 5. The injected expression executes before or alongside `research_run.py`. 6. The attacker's ...[truncated 867 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not construct the invocation by concatenating a shell command string. - Launch Python with a process API that accepts an argument array, such as Python's `subprocess.run([...], shell=False)`. - Pass the exact user question as one argument without shell parsing: ```python subprocess.run( [ "python3", runner_path, "--query", user_question, "--template-id", template_id, "--output", output_path, ], check=True, shell=False, ) ``` - If an interactive shell is unavoidable, pass the query through a securely assigned environment variable or apply robust platform-specific argument quoting. Do not rely only on surrounding the value with double quotes. - Validate `template_id` separately against the expected identifier format. - Construct the output path using a filesystem API rather than shell command substitution. - Add tests using queries containing quotes, semicolons, newlines, backticks, `$()`, pipes, redirections, and option-like prefixes. - Explicitly instruct Agents that verbatim preservation applies to the data sent to the runner, not to raw insertion into executable shell text. ]]>
