T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:34
- Finding
- Arbitrary Python Code Execution Through Unsafe File Path Interpolation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 34–44 **Vulnerability Type**: Command and code injection through unsafe interpolation **Risk Level**: High The vulnerable instruction provides the following fallback extraction command. The file-path placeholder is rendered in English below for consistency: ```bash python -c " from docx import Document doc = Document(r'<FILE_PATH>') for p in doc.paragraphs: print(p.text) for table in doc.tables: for row in table.rows: print('\t'.join(cell.text for cell in row.cells)) " ``` ### Technical Analysis The Skill instructs the Agent to replace a placeholder embedded directly inside Python source code with a user-provided document path. The path is placed within a raw single-quoted Python string: ```python doc = Document(r'<FILE_PATH>') ``` Raw strings do not prevent quote termination. A crafted path containing a single quote can close the string literal and introduce attacker-controlled Python expressions or statements. Because the entire generated program is supplied to `python -c`, injected Python runs with the same operating-system identity, environment, working directory, file access, and network access as the Agent process. The surrounding shell command also creates an additional parsing layer. Depending on how the Agent performs substitution, shell-sensitive content in the path may produce further command-construction hazards. This issue does not independently elevate operating-system privileges. Its severity arises from converting an otherwise passive document path into executable code under the Agent's existing privileges. ### Attack Path 1. An attacker supplies a novelty-report document with a deliberately crafted filename or recommends a crafted path to the Agent. 2. The normal document-reading operation fails, returns corrupted text, or appears incomplete, causing the documented fallback procedure to be used. 3. The Agent substitutes the attacker-controlled path ...[truncated 1213 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never interpolate a user-controlled path into Python source code or a dynamically constructed shell command. Pass the path as a separate positional argument: ```bash python -c ' import sys from pathlib import Path from docx import Document path = Path(sys.argv[1]).resolve(strict=True) if path.suffix.lower() != ".docx": raise ValueError("Only DOCX files are accepted") doc = Document(path) for paragraph in doc.paragraphs: print(paragraph.text) for table in doc.tables: for row in table.rows: print("\t".join(cell.text for cell in row.cells)) ' -- "$FILE_PATH" ``` Apply the following additional controls: 1. Invoke processes with an argument array rather than through a shell whenever the tool API supports it. 2. Canonicalize the path and require it to remain within an approved workspace directory. 3. Reject unexpected extensions, symbolic links where inappropriate, non-regular files, and paths outside the project workspace. 4. Use a fixed, reviewed extraction script instead of generating source code dynamically. 5. Run document extraction in a restricted sandbox with minimal filesystem access, no unnecessary credentials, and no network access. 6. Apply equivalent argument separation and path validation when invoking `antiword`, `textract`, or other fallback utilities. 7. Treat document filenames, paths, and document contents as untrusted input regardless of who supplied them. ]]>
