T09 · Insecure Skill Coding Practices
- Location
scripts/scaffold_hjb_problem.py:213- Finding
Unvalidated problem slug allows arbitrary file creation outside the project directory
- Content
View full analysis
None: path.parent.mkdir(parents=True, exist_ok=True) if path.exists(): raise FileExistsError(f"File already exists: {path}") path.write_text(content, encoding="utf-8") ``` ### Technical Analysis The value supplied through `--name` is only stripped and converted to lowercase. It is not validated as a Python identifier or restricted to a safe slug format. Path separators, `..` components, and absolute path syntax can consequently become part of the destination passed to `Path`. Python path composition normalizes traversal components when the path is used by the filesystem. In addition, if a later path component is absolute, `pathlib` can discard preceding components. The generated filen ...[truncated 2285 chars]- Remediation
View remediation
Path: destination = (repo_root / relative_path).resolve() try: destination.relative_to(repo_root) except ValueError as exc: raise ValueError(f"Output path escapes repository root: {destination}") from exc return destination ``` 3. Build destinations exclusively from validated relative components: ```python config_path = safe_destination( Path("src") / "configs" / f"{module_slug}_config.py" ) ``` 4. Reject all absolute paths, path separators, `.` components, and `..` components even if additional validation is added elsewhere. 5. Where hostile local filesystem state is in scope, account for symbolic links and time-of-check/time-of-use races. Avoid following untrusted symlinks and use atomic, exclusive file creation rather than a separate existence check followed by `write_text()`. 6. Run scaffolding with the minimum filesystem permissions required and avoid executing it from privileged or broadly writable automation contexts. ]]>
