T09 · Insecure Skill Coding Practices
- Location
mineru_api.py:220- Finding
Unvalidated ZIP Extraction Allows Path Traversal and Arbitrary File Overwrite
- Content
View full analysis
str: """Download results to the specified directory""" url = data.get("full_zip_url") if not url: return None # If no directory is specified, use the default result directory if out_dir is None: out_dir = "result" zip_path = os.path.join(out_dir, "result.zip") os.makedirs(out_dir, exist_ok=True) print(f"📥 Downloading...") r = requests.get(url, stream=True) with open(zip_path, "wb") as f: for c in r.iter_content(8192): f.write(c) with zipfile.ZipFile(zip_path, "r") as z: z.extractall(out_dir) os.remove(zip_path) return out_dir ``` ### Technical Analysis The `download()` function obtains an archive URL from the MinerU API response, downloads the content, and passes the resulting archive directly to `ZipFile.extractall()` without explicitly validating archive member paths. A malicious or compromised archive can contain absolute paths or traversal components such as `../../`. If these entries are not rejected by the deployed Python runtime or extraction environment, extraction can cause files to be written outside the intended `~/.openclaw/MinerU_Results/` directory. The download operation also lacks an HTTP timeout, response status validation, content-type validation, archive-size limit, and integrity verification. Consequently, an invalid or unbounded response could be stored and processed, increasing the potential for denial of service or processing of attacker-controlled content. ### Attack Path 1. An attacker compromises or impersonates the MinerU result service, its storage endpoint, or another component capable of influencing the `full_zip_url` response. 2. The attacker supplies a ZIP archive containing crafted entries such as ...[truncated 1410 chars]- Remediation
View remediation
> 16 if stat.S_ISLNK(mode): raise ValueError(f"Symbolic links are not allowed: {member.filename}" ...[truncated 339 chars]
