T09 · Insecure Skill Coding Practices
- Location
SKILL.md:150- Finding
Unsanitized Filename Interpolation Enables Python Code Injection
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 150–154
Vulnerability Type: Python code injection through unsafe shell-variable interpolation
Risk Level: HighVulnerable Code
bash # Get column names, types, null counts, sample values python3 -c " import csv, sys from collections import defaultdict, Counter with open('$FILE') as f:Technical Analysis
The command directly interpolates the shell variable
$FILEinto a Python string literal embedded in apython3 -cprogram. Shell quoting does not safely encode the value for the resulting Python source code.If an attacker can influence the input filename, a value containing a single quote and valid Python syntax can terminate the argument to
open(), inject additional statements, and comment out the remaining source as needed. The injected statements would execute under the privileges of the user or agent running the documented command.This is an exploitable coding pattern even though the project only contains documentation: the Skill explicitly directs an agent to execute the shown command while processing user-selected pipeline artifacts.
Attack Path
- An attacker supplies a CSV artifact with a specially crafted path or convinces the operator or agent to process such a path.
- The path is assigned to the
$FILEshell variable. - The agent follows the schema-extraction command in
SKILL.md. - The shell expands
$FILEdirectly inside the source passed topython3 -c. - Crafted quote characters terminate the intended Python string, allowing attacker-provided Python statements to become executable source.
- Python executes the injected statements with the current process privileges.
Exploitation depends on attacker control over the value placed in
$FILEand execution of the documented command.Impact Assessment
Successful exploitation permits arbitrary Python code execution with the privileges of ...[truncated 390 chars]
- Remediation
View remediation
Remediation Suggestions
Do not interpolate filenames into dynamically generated Python source. Pass the path as a positional argument and read it from
sys.argv:bash python3 - "$FILE" <<'PY' import csv import sys from collections import Counter, defaultdict file_path = sys.argv[1] with open(file_path, newline="", encoding="utf-8") as f: reader = csv.DictReader(f) rows = list(reader) schema = defaultdict( lambda: {"types": Counter(), "null_count": 0, "examples": []} ) for row in rows: for col, val in row.items(): schema[col]["null_count"] += 1 if not val.strip() else 0 schema[col]["types"][type(val).__name__] += 1 if len(schema[col]["examples"]) < 3: schema[col]["examples"].append(val) for col, info in schema.items(): null_pct = round(100 * info["null_count"] / len(rows), 1) print( f"{col}: {dict(info['types'])} | " f"null={null_pct}% | examples={info['examples']}" ) PYAdditional hardening measures:
- Move the validation implementation into a dedicated, reviewed Python script instead of constructing code through
python3 -c. - Parse paths through a structured argument parser and treat them strictly as data.
- Use
--where supported to separate options from path operands. - Run analysis with least privilege and in a sandbox when processing attacker-controlled artifacts.
- Add regression tests covering filenames containing quotes, spaces, newlines, shell metacharacters, and leading hyphens.
- Move the validation implementation into a dedicated, reviewed Python script instead of constructing code through
