T09 · Insecure Skill Coding Practices
Error
- Location
- remove_bg.py:34
- Finding
- Windows Shell Command Injection Through Attacker-Controlled Output Path<![CDATA[ ## Vulnerability Details **File Location**: `remove_bg.py`, lines 34–35 **Vulnerability Type**: OS command injection through `shell=True` **Risk Level**: High on Windows ```python if sys.platform.startswith('win'): subprocess.run(['start', str(out_path)], shell=True, check=False) ``` ### Technical Analysis The output path originates from the command-line argument `sys.argv[2]` and reaches `subprocess.run()` without validation or shell-safe handling. On Windows, the code invokes the command shell because `shell=True` is enabled. The `start` command is a shell built-in, and shell metacharacters contained in the attacker-controlled output path may therefore be interpreted as command separators or other shell syntax rather than as literal filename characters. Although the image must be saved before this branch is reached, Windows permits certain command-shell metacharacters, such as `&`, in filenames. Pillow is also explicitly instructed to save in PNG format, so the output filename does not need a conventional extension for the save operation to succeed. Consequently, an attacker able to control the output argument may select a writable, syntactically valid filename that becomes dangerous when subsequently interpreted by the shell. The automatic viewer launch is not necessary for background removal and is not disclosed in the documented command behavior. On macOS and Linux, the external viewer is launched with `shell=False`, so this specific shell-injection path applies to the Windows branch. ### Attack Path 1. An attacker controls or influences the output-image argument passed to the skill. 2. The attacker supplies a writable Windows path whose filename contains command-shell syntax, such as an `&` command separator followed by another command. 3. `remove_background()` successfully writes PNG data to that path. 4. The same untrusted path is passed to `subprocess.run()` with `shell=True`. 5. The Windows command shell parses the metacharacters ...[truncated 655 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the automatic image-viewer launch. Saving the processed PNG should be the default and only behavior of this image-processing skill. 2. If opening the result is required, make it an explicit opt-in option rather than an automatic side effect. 3. Never pass user-controlled values through `shell=True`. On Windows, use a platform API such as `os.startfile()` after validation, or invoke a fixed trusted executable with `shell=False`. 4. Validate that the output has a `.png` suffix, as required by the documented interface. 5. Resolve and validate the output path against an approved workspace directory if the skill is intended to write only within that workspace. 6. Reject unexpected control characters and enforce a conservative filename policy as defense in depth. This validation must supplement—not replace—removal of `shell=True`. 7. Report viewer-launch failures separately and avoid treating external application execution as part of the core conversion operation. ]]>
