T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:20
- Finding
- Shell Command Injection Through Unsafely Interpolated Search Terms<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 20-29 **Vulnerability Type**: Shell command injection caused by unsafe interpolation of user-controlled input **Risk Level**: High ### Vulnerable Code ```text - Search for anime: python3 "{baseDir}/anilist_cli.py" anime --search "<keyword, Japanese title, or English title>" --top 1 - Search for anime by AniList ID: python3 "{baseDir}/anilist_cli.py" anime --id <numeric ID> - Search for a character: python3 "{baseDir}/anilist_cli.py" character --search "<character name>" --top 1 - Search for voice actors or staff: python3 "{baseDir}/anilist_cli.py" staff --search "<voice actor or staff name>" --top 1 ``` The original instructions use Chinese placeholder descriptions, but the command structure above faithfully represents the affected code. ### Technical Analysis The Skill instructs the Agent to construct shell command strings by placing user-supplied search terms inside double quotes. Double quotes do not neutralize all shell syntax. In common POSIX shells, command substitutions such as `$(command)` and backtick substitutions are still evaluated inside double-quoted strings. An input containing an embedded quote may also terminate the intended argument and introduce additional shell operators. The Python implementation uses `argparse` and does not directly invoke a shell, so the flaw does not originate in `anilist_cli.py`. The vulnerable boundary is the command-construction procedure prescribed by `SKILL.md`: the shell can interpret malicious syntax before Python receives the search argument. For example, if an Agent directly substitutes a search term containing `$(attacker_command)` into the documented command, the shell executes `attacker_command` and passes its output to the Python process as part of the argument. ### Attack Path 1. An attacker submits an anime, character, or staff search term containing shell syntax, such as a command substitution expression. 2. The A ...[truncated 1442 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Avoid shell-string execution entirely.** Invoke the script using an argument-vector API in which each argument is passed separately, for example: ```python subprocess.run( [ "python3", script_path, "anime", "--search", user_search, "--top", "1", ], shell=False, check=True, ) ``` 2. **Update the Skill instructions** to require structured argument-array execution and explicitly prohibit concatenating or interpolating user input into a shell command. 3. **Do not rely only on double quotes.** If the available execution interface unavoidably accepts a shell string, apply robust platform-specific argument quoting, such as Python's `shlex.quote` for a known POSIX shell. Argument-array execution remains strongly preferred. 4. **Validate non-search parameters strictly.** Continue enforcing integer parsing for AniList IDs and result limits. Reject unexpected control characters where they are unnecessary. 5. **Apply least privilege.** Run the Skill in a restricted environment with minimal filesystem access, no unnecessary secrets, and constrained outbound networking so that any command-injection impact is limited. 6. **Add adversarial tests** covering command substitutions, backticks, embedded quotes, semicolons, pipes, redirections, newlines, and shell metacharacters. Verify that each value reaches `argparse` as one literal argument and is never evaluated by a shell. ]]>
