T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:18
- Finding
- Shell Command Injection Through Unescaped Tool Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 18-62 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```yaml execution: command: python3 {{SKILL_DIR}}/sync.py sync --config "{{config}}" --vault "{{vault}}" --format "{{format}}" output_format: markdown ``` ```yaml execution: command: python3 {{SKILL_DIR}}/sync.py add-substack --url "{{url}}" --config "{{config}}" output_format: markdown ``` ```yaml execution: command: python3 {{SKILL_DIR}}/sync.py add-ghost --url "{{url}}" --api-key "{{api_key}}" --config "{{config}}" output_format: markdown ``` ```yaml execution: command: python3 {{SKILL_DIR}}/sync.py list --config "{{config}}" output_format: markdown ``` ```yaml execution: command: python3 {{SKILL_DIR}}/sync.py config --config "{{config}}" output_format: markdown ``` ### Technical Analysis User-controlled tool arguments are interpolated directly into command strings. Surrounding arguments with double quotes is not sufficient shell escaping: command substitutions such as `$(...)` may still be evaluated, while an embedded quotation mark can terminate the quoted argument and introduce additional shell syntax. Exploitation depends on whether the Skill runtime executes these command templates through a shell. If it does, the `url`, `api_key`, `config`, `vault`, or `format` values can become command-injection vectors. The vulnerability violates the separation that should exist between executable commands and untrusted argument data. ### Attack Path 1. An attacker supplies or persuades the Agent to use a malicious tool argument, such as a crafted source URL or vault path. 2. The value is inserted into one of the `command` templates without shell-safe argument handling. 3. The Skill runtime passes the expanded command to a shell. 4. The shell interprets command substitution, quotation termination, separators, or redirection contained in the malicious value. 5. The injecte ...[truncated 574 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Configure tool execution as an executable plus an argument array rather than a shell command string. - Invoke Python with shell execution disabled, equivalent to: ```python subprocess.run( ["python3", skill_script, "add-ghost", "--url", url, "--api-key", api_key, "--config", config], shell=False, check=True, ) ``` - Use the Skill framework’s structured argument mechanism if available. - If command strings are unavoidable, apply a framework-supported shell-escaping function to every dynamic value. Do not rely only on double quotes. - Validate URLs, filesystem paths, format values, and configuration names against strict expected formats. - Add security tests using values containing quotation marks, semicolons, command substitutions, newlines, and redirection operators. ]]>
