T09 · Insecure Skill Coding Practices
- Location
scripts/multimodal_understand.py:105- Finding
Arbitrary Image URL Fetching Enables Server-Side Request Forgery and Data Exfiltration
- Content
View full analysis
tuple[bytes, str | None]: """Download URL content and return (bytes, content_type_from_header).""" req = urllib.request.Request(url, headers={"User-Agent": "multimodal-image-understanding/1.0"}) ctx = ssl.create_default_context() with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp: if resp.status != 200: raise SystemExit(f"Error: image download failed, HTTP {resp.status}") ct = resp.headers.get("Content-Type", "").split(";")[0].strip().lower() or None return resp.read(), ct ``` ```python if _is_url(image): if image_mode == "base64": data, content_type = _download_url(image, timeout=timeout) mime = _guess_mime_from_url(image, content_type) b64 = base64.standard_b64encode(data).decode("ascii") return {"source": "base64", "mime": mime, "data": b64, "url": None} ``` ### Technical Analysis The `--image` argument accepts arbitrary HTTP or HTTPS URLs. When `image_mode` is set to `base64`, the application retrieves the supplied URL through `urllib.request.urlopen()` without applying destination restrictions. The implementation does not: - Reject loopback, private, link-local, multicast, reserved, or cloud metadata IP ranges. - Resolve and validate hostnames before connecting. - Revalidate the destination after DNS resolution. - Disable redirects or validate each redirect target. - Verify that the response body is a genuine supported image. - Apply a maximum response size to remote downloads. Python's URL handling follows HTTP redirects by default. Consequently, an initially public URL may redirect to an internal address. The respon ...[truncated 1906 chars]- Remediation
View remediation
