T09 · Insecure Skill Coding Practices
- Location
scripts/converter.py:565- Finding
Output Path Can Overwrite the Original Input Template
- Content
View full analysis
Vulnerability Details
File Location:
scripts/converter.py, lines 565-570
Vulnerability Type: Unsafe file overwrite
Risk Level: Mediumpython # Write converted file output_path = output_dir / input_path.name output_path.write_text(output_html, encoding="utf-8") # Write report report_path = output_dir / f"{input_path.stem}.report.txt" report = generate_report(input_path.name, result)Technical Analysis
The converter constructs the destination path by combining the user-controlled output directory with the input file's basename. It does not resolve and compare the source and destination paths before calling
write_text().If
--outputidentifies the input file's parent directory,output_pathresolves to the original input path. Python'sPath.write_text()truncates an existing file before writing, so the source template is replaced by the converted output. This contradicts the guarantee inSKILL.md, line 137:markdown - **Never modify the original file.** Converted output always goes to the output directory.The same behavior can overwrite another existing file with a matching basename in a different output directory. No confirmation, exclusive-create mode, backup, or explicit force option is required.
Attack Path
- A user, automation process, or Agent invokes the converter with an input template.
- The supplied output directory is the source template's parent directory, whether intentionally or through path normalization such as
.or... output_dir / input_path.nameresolves to the source file itself.output_path.write_text()truncates and replaces the original template.- If conversion flags exist, the only source copy may be replaced with warning comments and commented-out template content.
An equivalent unintended overwrite occurs when the selected output directory already contains an unrelated file with the same basename.
Impact Assessment
Exploitation does not grant additional s ...[truncated 305 chars]
- Remediation
View remediation
Remediation Suggestions
- Resolve and compare the source and destination paths before writing:
python input_resolved = input_path.resolve() output_path = (output_dir / input_path.name).resolve() if output_path == input_resolved: raise ValueError( "Output path resolves to the input file; refusing to overwrite the source." )-
Refuse to replace any existing destination by default. Use exclusive creation, such as
open("x", encoding="utf-8"), and add an explicit--forceoption if overwrite behavior is required. -
Apply equivalent collision checks to generated report and summary paths.
-
Write to a temporary file in the destination directory and atomically rename it after successful conversion to reduce corruption risk from interrupted writes.
-
Add tests covering:
- Output directory equal to the input parent directory.
- Source and output aliases involving relative paths or symbolic links.
- Existing destination files with matching basenames.
- Explicit overwrite behavior when a future
--forceoption is used.
-
Preserve the documented guarantee that original files are never modified, or revise the documentation if overwrite behavior is deliberately supported.
