T09 · Insecure Skill Coding Practices
- Location
scripts/main.py:704- Finding
Caller-Controlled Output Path Allows Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/main.py:638-642,scripts/main.py:704-705, andscripts/main.py:782-783
Vulnerability Type: Unrestricted file write and overwrite
Risk Level: MediumVulnerable Code
python parser.add_argument( "--output", type=str, default="results.json", help="输出文件路径" )python # 保存结果 with open(args.output, 'w', encoding='utf-8') as f: json.dump(output, f, indent=2, ensure_ascii=False)python viz_file = args.output.replace('.json', '_visualization.png') plt.savefig(viz_file, dpi=150, bbox_inches='tight')Technical Analysis
The
--outputargument accepts an arbitrary filesystem path. The program does not canonicalize the path, constrain it to a designated output directory, check whether it references a symbolic link, or require confirmation before replacing an existing file.The call to
open(args.output, 'w', ...)creates the selected file or truncates an existing writable file. Consequently, anyone who controls the command-line arguments can overwrite any file writable by the process.There is an additional filename-collision issue in visualization mode. If the output path does not contain the literal substring
.json, the following expression returns the original path unchanged:python args.output.replace('.json', '_visualization.png')In that case,
plt.savefig()writes image data to the same path that previously received the JSON output, corrupting or replacing the simulation result.Attack Path
-
An attacker, untrusted automation layer, or manipulated Agent controls the value passed to
--output. -
The attacker selects an existing file writable by the current process, for example:
bash python scripts/main.py --n-simulations 1 --output /home/user/important-file -
The program reaches
open(args.output, 'w', ...). -
The selected file is truncated and replaced with simulation JSON.
-
If
--visualizeis also enable ...[truncated 934 chars]
-
- Remediation
View remediation
Remediation Suggestions
- Use
pathlib.Pathto resolve and validate the output path. - Restrict generated files to a dedicated output directory.
- Verify after resolution that the path remains inside the permitted directory.
- Refuse to replace existing files by default. Require an explicit
--overwriteoption where replacement is intended. - Reject symbolic-link destinations or use platform-specific safe file-creation controls where hostile local users are in scope.
- Generate the visualization path independently so it can never equal the JSON path.
For example:
python from pathlib import Path output_root = Path("outputs").resolve() output_root.mkdir(parents=True, exist_ok=True) requested_name = Path(args.output).name json_path = (output_root / requested_name).resolve() if output_root not in json_path.parents: raise ValueError("Output path must be inside the output directory") if json_path.exists() and not args.overwrite: raise FileExistsError(f"Output already exists: {json_path}") with json_path.open("x" if not args.overwrite else "w", encoding="utf-8") as f: json.dump(output, f, indent=2, ensure_ascii=False) viz_path = json_path.with_name(f"{json_path.stem}_visualization.png") if viz_path == json_path: raise ValueError("Visualization and JSON paths must be different")The application should also document that it must run with the minimum filesystem privileges required.
- Use
