T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:40
- Finding
- Shell Command Injection Through Interpolated File Paths## Vulnerability Details **File Location**: `SKILL.md`, line 40 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash python "<skill_path>/scripts/kindle_notes_to_md.py" --override -o "<output_dir>/<书名>.md" "<用户提供的HTML路径>" ``` ### Technical Analysis The documented runtime command interpolates multiple variable values into a shell command: - The HTML path is supplied by the user. - The book title is derived from the user-controlled filename. - The output directory comes from an editable configuration file. Double quotes do not safely escape an argument when the interpolated value can itself contain a double quote. A malicious filename or path can close the surrounding quoted argument and append shell syntax. If the agent follows this instruction by passing the constructed string to a shell, the injected syntax will be interpreted as commands rather than as part of a filename. For example, a title derived from a filename resembling the following can break out of the output argument on a POSIX shell: ```text notes"; touch /tmp/skill-command-injection; #.html ``` Merely removing known filename metadata does not neutralize shell metacharacters. Quoting must be performed according to the target shell, or preferably avoided entirely through structured process execution. ### Attack Path 1. An attacker creates or provides a Kindle HTML export whose filename contains a double quote followed by shell syntax. 2. The user asks the agent to convert that file. 3. The agent derives the book title from the malicious filename as required by the Skill. 4. The agent substitutes the title and input path into the command documented in `SKILL.md`. 5. If the resulting command is executed through a shell, the malicious quote terminates the intended argument. 6. The shell interprets the remaining text as one or more commands and executes them with the privileges ...[truncated 513 chars]
- Remediation
- ## Remediation Suggestions - Do not construct a shell command by textual interpolation. - Invoke the converter through a process API that accepts an argument array and disables shell parsing. For example, use the equivalent of: ```python subprocess.run( [ sys.executable, script_path, "--override", "-o", output_path, input_path, ], shell=False, check=True, ) ``` - Derive and validate the output filename inside trusted Python code rather than in agent-generated shell text. - Reject path separators, control characters, null bytes, and platform-reserved filename characters from the derived title. - Resolve the intended output path and verify that it remains inside the configured output directory. - If a shell is unavoidable, apply correct platform-specific escaping to every dynamic argument. Simple double-quote wrapping is insufficient.
