T09 · Insecure Skill Coding Practices
Note
- Location
- SKILL.md:18
- Finding
- Command Injection Through User-Controlled CLI Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:6`, `SKILL.md:18`, `SKILL.md:42`, `SKILL.md:71-73`, and `SKILL.md:116` **Vulnerability Type**: Shell command injection through unsafe interpolation of user-controlled input **Risk Level**: High ### Vulnerable Code ```yaml allowed-tools: ["Bash(fdx status*)", "Bash(fdx call helpNarrative*)", "Bash(fdx call onboardingAssistant*)", "Bash(fdx call reportIssue*)", "Bash(fdx call getAppVersion*)"] ``` ```bash fdx call helpNarrative --question "<question>" ``` ```bash fdx call onboardingAssistant --question "<question>" ``` ```bash fdx call reportIssue \ --title "<short title>" \ --description "<detailed description>" ``` ```markdown 4. Submit the report: `fdx call reportIssue --title "..." --description "..." --severity <level>` ``` ### Technical Analysis The skill instructs the agent to insert user-provided questions, issue titles, and issue descriptions directly into Bash command strings. Placing input inside double quotes is insufficient protection when the resulting text is parsed as shell source. Bash still evaluates command substitutions such as `$(command)` and backtick substitutions inside double-quoted strings. Embedded quotation marks or other shell syntax may also alter the intended command structure. For example, if an agent directly replaces `<question>` with the following user input: ```text $(touch /tmp/fdx-command-injection) ``` the generated command becomes: ```bash fdx call helpNarrative --question "$(touch /tmp/fdx-command-injection)" ``` Bash executes `touch /tmp/fdx-command-injection` during command substitution before invoking `fdx`. The wildcard Bash permissions in line 6 increase the exposure. A command beginning with an allowed prefix such as `fdx call helpNarrative` may still contain command substitutions or appended shell syntax, depending on how the command allowlist is enforced. Prefix-based approval therefore does not establish an argument-level security bou ...[truncated 1624 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Do not construct shell source from user input.** Invoke `fdx` through a structured process API that accepts an executable and an argument array without using a shell. Conceptually: ```text executable: fdx arguments: - call - helpNarrative - --question - <user input as one opaque argument> shell: false ``` 2. **Replace generic Bash access with structured tools.** Define dedicated tool interfaces for `helpNarrative`, `onboardingAssistant`, and `reportIssue`, with typed fields for each parameter. 3. **Remove wildcard command permissions where possible.** Replace permissions such as: ```yaml Bash(fdx call helpNarrative*) ``` with argument-aware policies that cannot authorize shell operators, substitutions, redirections, or additional commands. 4. **If Bash is unavoidable, pass data through positional parameters rather than interpolating it into shell source.** Ensure the input is supplied as a separate process argument and is never evaluated with `eval`, `bash -c`, or equivalent mechanisms. 5. **Apply defense-in-depth validation.** Set reasonable length limits and reject control characters. Where operationally compatible, reject shell metacharacters such as backticks, `$(`, newlines, semicolons, pipes, and redirection operators. Validation must supplement—not replace—shell-free argument handling. 6. **Add adversarial tests.** Verify that values containing `$(id)`, backticks, quotes, semicolons, newlines, pipes, and redirections are passed literally to `fdx` and never executed by a shell. ]]>
