T09 · Insecure Skill Coding Practices
- Location
scripts/imagegen.py:352- Finding
API-Controlled Path Traversal and Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/imagegen.py:352-364
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: HighVulnerable Code
python result_url = item.get("resultUrl") if not result_url: continue ext = ".mp4" if "video" in task_type.lower() else ".png" filename = f"{task_type}_{task_id}_{i+1}{ext}" out_path = out_dir / filename download_file(result_url, out_path) # 尾帧 for item in succeeded: last_frame = item.get("lastFrameUrl") if last_frame: out_path = out_dir / f"{task_type}_{task_id}_lastframe.png" download_file(last_frame, out_path)Technical Analysis
The remotely supplied
taskTypevalue and generatedtaskIdare interpolated directly into local filenames. Neither value is normalized or checked for path separators,..components, absolute paths, or other unsafe characters.Joining an untrusted filename to
out_dirwith the/operator does not guarantee that the resulting path remains inside that directory. A crafted value containing traversal components can causeout_pathto resolve outside the intended download directory. Thedownload_filefunction subsequently opens that path inwbmode, which creates or overwrites the target file.This vulnerability depends on malicious or compromised API responses. It does not require the API key to be disclosed.
Attack Path
- The user submits an image-generation request to the configured API.
- The remote service, or an attacker controlling the service response, returns a crafted
taskIdortaskTypecontaining path traversal components. - The task response includes a
resultUrlorlastFrameUrlcontaining attacker-controlled content. - The client constructs a path such as
out_dir / "../../../../target_<id>.png". download_fileopens the resolved path usingwb.- An existing file writable by the current user is overwritten, ...[truncated 532 chars]
- Remediation
View remediation
Remediation Suggestions
- Do not derive local filenames from remote metadata. Generate filenames locally with UUIDs or strictly formatted counters.
- If remote identifiers must be retained, allow only a narrow character set such as ASCII letters, digits, hyphens, and underscores.
- Explicitly reject
/,\,.., absolute paths, drive prefixes, control characters, and reserved filesystem names. - Resolve both the output directory and candidate path, then verify that the candidate remains beneath the output directory using
Path.relative_to()or an equivalent containment check. - Consider creating files with exclusive mode to prevent unintended overwrites.
- Apply the same validation to normal result files and last-frame files.
Example containment strategy:
python import re import uuid out_dir = Path(output_dir).resolve() out_dir.mkdir(parents=True, exist_ok=True) safe_task_id = re.sub(r"[^A-Za-z0-9_-]", "_", str(task_id)) filename = f"image_{safe_task_id}_{i + 1}_{uuid.uuid4().hex}.png" out_path = (out_dir / filename).resolve() out_path.relative_to(out_dir)
