T09 · Insecure Skill Coding Practices
- Location
scripts/media_gen_client.py:84- Finding
Unvalidated Server-Provided URL Enables Arbitrary Network Requests
- Content
View full analysis
Vulnerability Details
File Location:
scripts/media_gen_client.py, lines 84–99 and 258–263
Vulnerability Type: Unvalidated remote URL / server-side request forgery
Risk Level: MediumVulnerable Code
python def _download_to_file(url: str, out_path: str, timeout_s: int = 300) -> Dict[str, Any]: """ Download a (possibly signed) URL to local file. Designed for OSS signed URLs returned by video generation tasks. """ os.makedirs(os.path.dirname(out_path) or ".", exist_ok=True) req = urllib.request.Request(url, headers={"User-Agent": "OpenClaw-Media-Gen/1.0"}) try: with urllib.request.urlopen(req, timeout=timeout_s) as resp, open(out_path, "wb") as f: total = 0 while True: chunk = resp.read(1024 * 1024) # 1MB if not chunk: break f.write(chunk) total += len(chunk) return {"success": True, "saved_to": out_path, "bytes": total}python if status == "SUCCEEDED" and getattr(args, "download", False): video_url = (resp.get("output") or {}).get("video_url") or (resp.get("output") or {}).get("videoUrl") if video_url: out_path = args.out or _safe_filename("mp4") dl = _download_to_file(video_url, out_path) resp = {**resp, "download": dl}Technical Analysis
The video download URL comes from the remote task-status response and is passed directly to
urllib.request.urlopen. The code does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect destinations.Consequently, a compromised or malicious API response could direct the client to an unintended endpoint accessible from the user's execution environment. Potential destinations include loopback interfaces, private-network services, link-local services, or attacker-controlled hosts. Because
urllibfollows ...[truncated 1770 chars]- Remediation
View remediation
Remediation Suggestions
- Permit only
httpsdownload URLs. - Maintain an allowlist of documented AISA media-storage hostnames or hostname suffixes.
- Resolve the hostname before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IP addresses.
- Protect against DNS rebinding by ensuring the validated address is the address used for the connection.
- Disable automatic redirects or validate the scheme, hostname, port, and resolved address of every redirect target.
- Reject URLs containing unexpected credentials, ports, or malformed hostnames.
- Require explicit user confirmation when a returned media URL uses an unexpected domain.
- Consider having the API return an opaque media identifier that is downloaded through a fixed trusted endpoint rather than accepting an arbitrary URL.
- Permit only
