T09 · Insecure Skill Coding Practices
- Location
scripts/common.py:350- Finding
Unrestricted URL Retrieval Enables SSRF and Local File Reads
- Content
View full analysis
Path: """Download a file from URL to local path.""" output_path.parent.mkdir(parents=True, exist_ok=True) request = urllib.request.Request(url, method="GET") with urllib.request.urlopen(request) as response: output_path.write_bytes(response.read()) return output_path ``` The caller passes the command-line URL directly to this function: ```python log_params("Download video started", url=args.url, name=args.name) if args.output: output_path = Path(args.output) else: output_path = default_output_path( "videos", args.scene, suffix=".mp4", name=args.name ) download_file(args.url, output_path) ``` ### Technical Analysis The download function passes a caller-controlled URL directly to `urllib.request.urlopen` without validating: - The URI scheme - The destination hostname - The resolved IP address - Redirect targets - URL-embedded credentials - Whether the destination is a loopback, private, link-local, or reserved address - Whether the response originates from an expected Volcengine media host `urllib.request` supports handlers beyond ordinary HTTPS retrieval. Depending on the runtime configuration, a `file:` URI can read a local file. HTTP and HTTPS URLs can also target local services, private network hosts, or cloud metadata endpoints. The same helper is used to download generated videos. The broad URL support exceeds the minimum privilege required for that function, which only needs to retrieve media from known or validated remote sources. ### Attack Path 1. An attacker persuades the Agent or user to invoke `download_video.py` with a crafted `--url`. 2. The URL identifies a local file, loopbac ...[truncated 1164 chars]- Remediation
View remediation
