T09 · Insecure Skill Coding Practices
- Location
scripts/orchestrate_story.py:389- Finding
Path Traversal Through Unvalidated Shot and Task Identifiers
- Content
View full analysis
None: output_path.parent.mkdir(parents=True, exist_ok=True) urllib.request.urlretrieve(video_url, output_path) ``` ### Technical Analysis The storyboard validator requires a nonempty, unique shot identifier but does not restrict path separators, `..` components, absolute-path syntax, control characters, or identifier length. The `task_id` returned by the delegated `seedance.py` process is also not validated. Both values are interpolated directly into a filename. When the resulting value is joined to `run_dir`, embedded traversal components can cause the normalized destination to resolve outside the intended run directory. The code does not resolve the destination and verify t ...[truncated 1781 chars]- Remediation
View remediation
str: if not isinstance(value, str) or not SAFE_ID.fullmatch(value): raise OrchestratorError(f"Invalid {field}") return value ``` 2. Resolve the destination and enforce containment beneath the run directory: ```python base = run_dir.resolve() destination = (base / filename).resolve() try: destination.relative_to(base) except ValueError: raise OrchestratorError("Output path escapes the run directory") ``` 3. Generate local filenames independently of remote identifiers. Store the original task ID only as JSON metadata. 4. Reject absolute paths, path separators, `.` and `..` components, null bytes, control characters, and excessively long values. 5. Avoid silently overwriting existing files. Use exclusive creation or a collision-resistant, locally generated filename. 6. Add regression tests using traversal payloads in both `shot_id` and `task_id`, including mixed separators and deeply nested parent-directory components. ]]>
