T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/main.py:125
- Finding
- Unrestricted Output Path Allows Arbitrary File Overwrite## Vulnerability Details **File Location**: `scripts/main.py:125-129, 152-154` **Vulnerability Type**: Unrestricted file write / arbitrary file overwrite **Risk Level**: Medium ### Vulnerable 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 `--output` argument accepts an arbitrary path and passes it directly to `open()` without canonicalization, workspace-boundary enforcement, file-type validation, or symlink protection. Opening the supplied path in `w` mode 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 1. An attacker gains control over or influences the command-line arguments used to invoke the Skill. 2. 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 ``` 3. The program passes the path directly to `open(..., 'w')`. 4. If the process has write permission, the target file is created or truncated. 5. The program replaces its contents with generated explanation JSON, potentially disrupting the affected applicatio ...[truncated 702 chars]
- Remediation
- ## Remediation Suggestions 1. Create a dedicated output directory and resolve both the directory and requested destination to canonical absolute paths. 2. 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") ``` 3. Reject absolute user-supplied paths and parent-directory traversal components. 4. Reject symbolic links and non-regular targets. Where supported, use no-follow operating-system flags to reduce time-of-check/time-of-use risks. 5. If overwriting is unnecessary, create files exclusively with mode `x` so existing files cannot be silently truncated. 6. If overwriting is required, write to a securely created temporary file in the same approved directory and atomically replace only an explicitly authorized destination. 7. Restrict the output extension to `.json` if other file types are not required. 8. Run the Skill with a least-privileged account whose write access is limited to the designated workspace. 9. Add tests covering absolute paths, `../` traversal, symlink targets, existing files, special files, and paths outside the approved output directory.
