T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:132- Finding
Unrestricted Output Path Allows Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py, lines 132 and 149–150
Vulnerability Type: Unrestricted file write and path traversal
Risk Level: MediumVulnerable Code
python parser.add_argument("--output", "-o", default="journal_club_outline.txt", help="Output file")python with open(args.output, 'w') as f: f.write(outline)Technical Analysis
The command-line caller has complete control over
args.output, which is passed directly toopen()in write mode. The implementation performs no path normalization, workspace-boundary validation, parent-directory traversal rejection, symlink check, target-type check, or overwrite confirmation.Python's
'w'mode creates a missing file or truncates an existing file before writing. It also follows symbolic links. Consequently, an attacker who can influence the script's command-line arguments can select any target writable by the process. Relative traversal paths such as../../targetand writable absolute paths are accepted.This behavior conflicts with the intended control in
SKILL.md, which states that output should be restricted to the workspace.Attack Path
- An attacker influences the
--outputargument supplied by an agent, automation system, or user. - The attacker supplies a traversal path, writable absolute path, or path to a symbolic link, for example:
bash python scripts/main.py \ --title "Example" \ --output "../../writable-target" - The script passes that path directly to
open(args.output, 'w'). - The operating system resolves the path or follows the symbolic link.
- If the process has write permission, the selected file is created or truncated and replaced with the generated outline.
Impact Assessment
Exploitation does not grant privileges beyond those already held by the Python process. However, it allows an attacker to overwrite any file writable ...[truncated 472 chars]
- An attacker influences the
- Remediation
View remediation
Remediation Suggestions
- Define an explicit, trusted workspace output directory in configuration rather than accepting unrestricted destinations.
- Resolve the requested path and verify that it remains under the resolved workspace root:
python from pathlib import Path workspace = Path("outputs").resolve() workspace.mkdir(parents=True, exist_ok=True) requested = (workspace / args.output).resolve() if requested == workspace or workspace not in requested.parents: parser.error("Output path must remain inside the output workspace") - Prefer accepting only a filename rather than an arbitrary path, and reject absolute paths and
..components. - Reject symbolic links and existing non-regular targets. Where practical, open files using operating-system flags that prevent symlink following.
- Use exclusive creation (
'x') by default to prevent silent truncation, or require an explicit trusted--overwriteoption. - Apply restrictive file permissions and run the skill with the minimum necessary filesystem privileges.
- Add tests for absolute paths,
../traversal, nested traversal, symlink targets, existing files, and destinations outside the workspace.
