T09 · Insecure Skill Coding Practices
- Location
SKILL.md:203- Finding
Python Source Injection Through Unescaped File Paths
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, line 203
Vulnerability Type: Python source injection through unsafe string interpolation
Risk Level: HighVulnerable Code
bash python3 -c "import ast; ast.parse(open('$file').read())"Technical Analysis
The validation command interpolates
$filedirectly into Python source code inside a single-quoted string. The file path is derived from findings in.beagle/ai-writing-review.json, but the Skill does not escape the value or validate its format.A path containing a single quote can terminate the argument to
open()and append arbitrary Python statements. Shell quoting does not prevent this because the malicious content becomes part of the source passed topython3 -c.Attack Path
- An attacker commits or generates a poisoned
.beagle/ai-writing-review.json. - A finding identifies a Python file using a path containing Python syntax, such as a quote followed by attacker-controlled statements.
- The Skill processes the finding and assigns that path to
$file. - During validation,
$fileis embedded directly in thepython3 -cprogram. - The injected Python statements execute with the same operating-system privileges as the Agent.
Impact Assessment
Successful exploitation provides arbitrary local code execution under the Agent's account. The attacker could read or alter any files available to that account, access inherited environment variables and credentials, execute subprocesses, or tamper with the checked-out repository. The flaw does not itself elevate privileges beyond the Agent's operating-system account.
- An attacker commits or generates a poisoned
- Remediation
View remediation
Remediation Suggestions
Pass the file path as a positional argument instead of embedding it in executable Python source:
bash python3 -c \ 'import ast, pathlib, sys; ast.parse(pathlib.Path(sys.argv[1]).read_text())' \ -- "$file"In addition:
- Validate every path before invoking a validator.
- Resolve it to a canonical path and require it to remain under the Git worktree.
- Reject null bytes, absolute paths, traversal components, and symlinks that resolve outside the worktree.
- Validate the JSON report against a strict schema before processing it.
- Use subprocess argument arrays rather than constructing executable source or shell command strings.
