T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:82
- Finding
- Unquoted Remote URL Interpolation Can Enable Shell Command Injection<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 82–88 **Vulnerability Type**: Shell command injection through unsafe interpolation of remote response data **Risk Level**: High ### Vulnerable Code ```shell curl --fail --location <deliverable-url> --output <downloaded-file> for file in <downloaded-files>; do expected_mime=<expected-MIME-or-family-pattern-for-this-file> test -s "$file" [[ "$(file --brief --mime-type "$file")" == $expected_mime ]] done ``` ### Technical Analysis The documented command inserts `<deliverable-url>` and `<downloaded-file>` directly into a shell command without requiring quoting, validation, or safe argument construction. The deliverable URL is derived from a remote RunAPI response and therefore crosses a trust boundary. If an agent replaces the placeholders textually and executes the resulting shell command, shell metacharacters contained in a malicious or compromised response—such as command separators, substitutions, redirections, or newline characters—can be interpreted as shell syntax instead of data. The output filename and expanded downloaded-file list present similar risks if they are externally influenced. The use of `curl --location` also permits redirects without documenting protocol or destination restrictions. Although redirects alone do not establish command execution, they increase exposure to unintended network destinations and untrusted content. ### Attack Path 1. An attacker compromises, impersonates, or otherwise influences the API endpoint or task response that provides the deliverable URL. 2. The response contains a URL value with shell metacharacters or command-substitution syntax. 3. An agent follows the Skill and substitutes that value directly for `<deliverable-url>` in the documented shell command. 4. The shell parses the attacker-controlled characters as command syntax because the value is not safely quoted or passed as an isolated argument. 5. The injected command execut ...[truncated 987 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Store every remotely supplied URL in a variable and quote it whenever passed to a command: ```shell deliverable_url='validated URL' downloaded_file='validated local path' curl --fail --location --proto '=https' -- "$deliverable_url" \ --output "$downloaded_file" ``` 2. Validate the URL before invoking `curl`: - Require the `https` scheme. - Reject control characters, embedded newlines, and malformed URLs. - Allowlist expected provider or object-storage hostnames where operationally feasible. - Reject embedded credentials and unexpected ports. 3. Constrain redirects: - Retain HTTPS-only protocol restrictions for both initial requests and redirects. - Set an explicit redirect limit. - Revalidate redirect destinations or restrict them to approved domains where possible. 4. Generate local output paths internally rather than deriving them from remote values. Use a private temporary directory created with `mktemp -d`, restrictive permissions, and collision-resistant filenames. 5. Avoid textual placeholder substitution into shell source. Prefer a process-execution API that passes arguments as an array without invoking a shell. 6. Quote all array and loop expansions. A safer Bash pattern is: ```shell for file in "${downloaded_files[@]}"; do test -s "$file" actual_mime="$(file --brief --mime-type -- "$file")" [[ "$actual_mime" == "$expected_mime" ]] || exit 1 done ``` 7. Update the Skill instructions to state explicitly that API response fields are untrusted data and must never be evaluated, interpolated into shell source, or used as executable command fragments. ]]>
