T09 · Insecure Skill Coding Practices
- Location
scripts/batch_generate.py:151- Finding
Configuration-Controlled Path Traversal Allows Writes Outside the Output Directory
- Content
View full analysis
- Remediation
View remediation
str: if not isinstance(value, str) or not SAFE_COMPONENT.fullmatch(value): raise ValueError(f"Invalid {field}: {value!r}") return value ``` 2. Validate every configuration-derived path component before constructing a path: ```python name = validate_component(asset["name"], "asset name") category = validate_component( asset.get("category", "uncategorized"), "asset category", ) ``` 3. Resolve and enforce containment for defense in depth: ```python def safe_child(root: Path, *parts: str) -> Path: root = root.resolve() candidate = root.joinpath(*parts).resolve() if not candidate.is_relative_to(root): raise ValueError(f"Path escapes output root: {candidate}") return candidate ``` For Python versions where `Path.is_relative_to()` is unavailable, use `candidate.relative_to(root)` inside a `try` block. 4. Construct both paths through the containment helper: ```python raw_path = safe_child(raw_dir, f"{name}_raw.png") out_dir = safe_child(output_base, category, name) ``` 5. Reject absolute paths, `.` and `..` components, empty names, null bytes, and both platform-specific path separators. 6. If configuration files may originate from untrusted users, document that they are untrusted input and fail closed before creating any directories or invoking subprocesses. ]]>
