T09 · Insecure Skill Coding Practices
- Location
scripts/image_generator.py:110- Finding
Unrestricted retrieval of server-provided image URLs enables SSRF
- Content
View full analysis
None: # Security note: only accept HTTP/HTTPS; print the host before downloading; # enforce a maximum 50 MB size limit. from urllib.parse import urlparse parsed = urlparse(url) if parsed.scheme not in ("http", "https"): raise ValueError(f"Refusing to download a non-HTTP(S) URL: {parsed.scheme}") print(f"Downloading image host={parsed.netloc} path={parsed.path[:80]}") resp = requests.get(url, stream=True, timeout=REQUEST_TIMEOUT_SECS) resp.raise_for_status() ctype = resp.headers.get("content-type", "") if ctype and not ctype.startswith("image/"): print(f"Non-image Content-Type: {ctype} (still attempting to write it)") MAX_BYTES = 50 * 1024 * 1024 written = 0 with open(output_path, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): written += len(chunk) if written > MAX_BYTES: f.close() os.remove(output_path) raise ValueError( f"Download exceeded the {MAX_BYTES}-byte limit and was discarded: {url[:80]}" ) f.write(chunk) ``` ### Technical Analysis The image generator accepts image URLs extracted from a remote image-generation response. It verifies only that the URL uses the `http` or `https` scheme. It does not reject destinations resolving to loopback, private, link-local, reserved, multicast, or cloud metadata addresses. The `requests` library follows redirects by default for GET requests. Consequently, validating only the initial URL would remain insufficient even if the initial hostname appeared trustworthy: an external endpoint could redirect the request to an int ...[truncated 1719 chars]- Remediation
View remediation
