T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/translate.py:111
- Finding
- Command and Python Code Injection Through Unsanitized Path Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/translate.py:14-19`, `scripts/translate.py:111-118`, and `scripts/translate.py:137-138` **Vulnerability Type**: Command injection and generated Python code injection **Risk Level**: High ### Vulnerable Code Command templates directly embed path parameters into executable Bash and Python strings: ```python r"list|show|find.*files?|ls": { "cmd": "ls -la {path}", "python": "import os; print('\\n'.join(os.listdir('{path}')))" }, # File content viewing r"cat|view|show.*content|read.*file": { "cmd": "cat {file}", "python": "with open('{file}') as f: print(f.read())" }, ``` The path extractor accepts arbitrary non-whitespace characters in an absolute path: ```python # Extract file paths file_matches = re.findall(r'[\w\-./]+\.[\w]+|[\w\-./]+/|/[^\s]+', text) if file_matches: for m in file_matches: if '.' in m or m.endswith('/'): params["file"] = m params["path"] = m break ``` The extracted values are then inserted into command and source-code templates without context-aware escaping: ```python cmd = commands["cmd"].format(**params) py_cmd = commands["python"].format(**params) ``` ### Technical Analysis The regular-expression branch `/[^\s]+` accepts every non-whitespace character after an initial slash. This includes shell metacharacters such as semicolons, command substitutions, backticks, redirection operators, and quote characters. The resulting attacker-controlled string is passed directly to `str.format()` and inserted into Bash command templates. The path is not quoted consistently and is never escaped with a shell-aware mechanism such as `shlex.quote()`. Consequently, a path can terminate the intended command argument and introduce another shell operation. The same data is embedded between quotes in generated Python source. An attacker can include quote characters that terminate the intended string literal and introduce arbitr ...[truncated 2002 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Avoid generating shell source from untrusted input.** Represent commands as structured argument arrays, for example: ```python ["cat", user_path] ``` Downstream execution should use `subprocess.run(arguments, shell=False, check=True)`. 2. **Apply context-aware escaping when textual Bash output is unavoidable.** Quote each untrusted argument with `shlex.quote()`: ```python import shlex safe_file = shlex.quote(params["file"]) ``` Escaping must occur after parsing and immediately before insertion into a shell command. 3. **Do not insert input into generated Python string literals.** Use `repr()` or structured serialization: ```python safe_file_literal = repr(params["file"]) py_cmd = f"with open({safe_file_literal}) as f: print(f.read())" ``` Prefer passing the path as an external argument rather than generating Python source. 4. **Validate path inputs.** Reject control characters, newlines, NUL bytes, and malformed paths. If the intended use permits access only within a specific directory, resolve the path with `pathlib.Path.resolve()` and verify that it remains under the authorized root. 5. **Handle option-like filenames safely.** Use the `--` end-of-options marker where supported, such as `cat -- "$file"`. 6. **Separate destructive operations from ordinary translation.** Commands such as `sed -i` should require explicit confirmation and should provide a non-destructive preview or backup option first. 7. **Add security regression tests.** Include paths containing semicolons, `$()`, backticks, single and double quotes, redirection operators, spaces, newlines, and leading hyphens. Verify that each value remains one literal argument and cannot alter command structure. 8. **Warn users about execution boundaries.** Clearly state that generated output must be reviewed before execution, particularly when input may originate from an untrusted party. ]]>
