T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:125- Finding
Unrestricted Output Path Allows Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:125-129, 152-154
Vulnerability Type: Unrestricted file write / arbitrary file overwrite
Risk Level: MediumVulnerable Code
python parser.add_argument( "--output", "-o", type=str, help="Output JSON file path (optional)" )python if args.output: with open(args.output, 'w', encoding='utf-8') as f: f.write(output) print(f"Explanation saved to: {args.output}")Technical Analysis
The
--outputargument accepts an arbitrary path and passes it directly toopen()without canonicalization, workspace-boundary enforcement, file-type validation, or symlink protection.Opening the supplied path in
wmode creates the file if it does not exist and immediately truncates it if it already exists. Absolute paths, parent-directory traversal sequences, and paths resolving through symbolic links are not rejected.This behavior conflicts with the security controls described in
SKILL.md, which identify path-traversal validation and restricting output to the workspace as required safeguards.The attacker cannot choose arbitrary file contents because the program writes generated JSON. Nevertheless, truncating and replacing a writable file is sufficient to corrupt configuration, application data, scripts, or other files accessible to the process.
Attack Path
- An attacker gains control over or influences the command-line arguments used to invoke the Skill.
- The attacker supplies an absolute path, a path containing parent-directory traversal, or a path that resolves through a symbolic link:
bash python scripts/main.py \ --concept thrombosis \ --output ../../target-file - The program passes the path directly to
open(..., 'w'). - If the process has write permission, the target file is created or truncated.
- The program replaces its contents with generated explanation JSON, potentially disrupting the affected applicatio ...[truncated 702 chars]
- Remediation
View remediation
Remediation Suggestions
- Create a dedicated output directory and resolve both the directory and requested destination to canonical absolute paths.
- Verify that the resolved destination remains beneath the approved output directory:
python from pathlib import Path output_root = Path("output").resolve() output_root.mkdir(parents=True, exist_ok=True) destination = (output_root / args.output).resolve() if output_root not in destination.parents: raise ValueError("Output path must remain inside the output directory") - Reject absolute user-supplied paths and parent-directory traversal components.
- Reject symbolic links and non-regular targets. Where supported, use no-follow operating-system flags to reduce time-of-check/time-of-use risks.
- If overwriting is unnecessary, create files exclusively with mode
xso existing files cannot be silently truncated. - If overwriting is required, write to a securely created temporary file in the same approved directory and atomically replace only an explicitly authorized destination.
- Restrict the output extension to
.jsonif other file types are not required. - Run the Skill with a least-privileged account whose write access is limited to the designated workspace.
- Add tests covering absolute paths,
../traversal, symlink targets, existing files, special files, and paths outside the approved output directory.
