T09 · Insecure Skill Coding Practices
- Location
src/reporter.py:126- Finding
Arbitrary File Overwrite Through Unsanitized Report Filenames
- Content
View full analysis
str: """Generate HTML report.""" if filename is None: filename = f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html" filepath = self.output_dir / filename template = Template(HTML_REPORT_TEMPLATE) html_content = template.render( timestamp=report.timestamp.strftime("%Y-%m-%d %H:%M:%S"), total=report.total, passed=report.passed, failed=report.failed, skipped=report.skipped, pass_rate=f"{report.pass_rate:.1f}", duration=f"{report.total_duration:.2f}", tests=[ { "name": r.name, "status": r.status, "duration": f"{r.duration:.3f}", "message": r.message } for r in report.results ] ) with open(filepath, "w") as f: f.write(html_content) return str(filepath) ``` The JSON and JUnit generators repeat the same unsafe construction: ```python filepath = self.output_dir / filename with open(filepath, "w") as f: json.dump(data, f, indent=2) ``` ```python filepath = self.output_dir / filename ... tree.write(filepath, encoding="utf-8", xml_declaration=True) ``` ### Technical Analysis The caller-supplied `filename` is joined directly to `self.output_dir` without validating whether it is an absolute path or contains traversal components such as `..`. `pathlib.Path` does not confine a joined path to its parent directory. An absolute filename causes the configured output directory to be discarded, while traversal components can resolve outside it. Each report generator then opens the resulting path in write mode or passes it to `ElementTree.write`, overwriting ...[truncated 1564 chars]- Remediation
View remediation
