T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:39
- Finding
- Arbitrary Shell Command Execution from Untrusted Acceptance Checklists<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 39-42, 92-104, and 153-164 **Vulnerability Type**: Command injection through untrusted checklist content **Risk Level**: High ### Vulnerable Code Snippets At lines 39-42, the Skill accepts a supplied checklist path without imposing a trusted-directory boundary: ```markdown ### If a path argument is provided - Directly use it as the checklist file path - Read the file and continue to Step 2 ``` At lines 92-104, commands embedded in preparation items are extracted and executed through Bash: ```markdown ### 3.1 `[AUTO]` Items — One-Time Command Execution 1. Extract the command from the backticks in the line 2. Execute it through Bash 3. Success → display `✓ [description]` and continue to the next item 4. Failure → analyze the output and attempt to fix simple problems: - Missing variables in `.env` → automatically append the variable - Compilation error → display the error, attempt a fix, and compile again - Version mismatch → report the actual version and use `AskUserQuestion`: “Continue” / “Abort” 5. Retry after remediation, for a maximum of **3 rounds** 6. If it still fails after 3 rounds → use `AskUserQuestion`: “Skip” / “Abort acceptance testing” ``` At lines 153-164, commands embedded in automated verification steps are likewise executed without validation: ```markdown #### `[A]` Steps — Automated Execution: 1. Extract the command from the backticks in the step 2. Execute it through Bash 3. Compare the actual output with the expected result after `→ Expected:` 4. **Match** → display `✓ [step description]` 5. **Mismatch** → analyze the cause and attempt remediation, such as restarting services or fixing configuration: - Retry the command, for a maximum of **3 rounds** - If remediation succeeds → display `✓ [step description] (passed after retry)` - If it still fails after 3 rounds → record the step as **failed**, display `✗ [step description]`, and include actual ...[truncated 3521 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Restrict checklist locations** - Resolve the supplied path to its canonical absolute path. - Require the resolved path to remain under the canonical `{workspace}/spec/` directory. - Reject `..` traversal, absolute external paths, and symlinks that escape the trusted directory. - Require the expected filename and file type where feasible. 2. **Do not interpret checklist text as arbitrary shell code** - Replace backtick command extraction with a structured action schema. - Define a small allowlist of supported executables and operations. - Represent commands as executable-and-argument arrays rather than shell strings. - Invoke programs without a shell where possible. 3. **Validate all requested operations** - Reject command substitution, redirection, pipes, command chaining, background execution, and shell metacharacters. - Validate paths, ports, environment variable names, and arguments against explicit schemas. - Reject executable paths outside approved tool directories. 4. **Require informed approval** - Display the exact executable, arguments, working directory, affected files, and expected network access before execution. - Require explicit user confirmation for commands not generated from a trusted built-in action. - Always require confirmation before editing `.env`, source code, or configuration. 5. **Apply least privilege and isolation** - Run acceptance commands in a sandbox or disposable container. - Mount only the required workspace paths and use read-only mounts where possible. - Disable network access by default and enable it only for documented test requirements. - Avoid exposing unrelated credentials or host environment variables to test processes. 6. **Constrain automatic remediation** - Permit only narrowly defined and reversible fixes. - Generate a proposed patch and request approval before applying it. - Record every changed file and provid ...[truncated 661 chars]
