T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/image.py:91
- Finding
- Unrestricted Image Download Enables Server-Side Request Forgery and Resource Exhaustion## Vulnerability Details **File Location**: `scripts/image.py`, lines 91-95 **Vulnerability Type**: Server-Side Request Forgery (SSRF), unbounded response handling, and unrestricted file output **Risk Level**: Medium ### Vulnerable Code ```python def download_image(image_url: str, output_path: str) -> str: resp = requests.get(image_url, timeout=60) resp.raise_for_status() with open(output_path, "wb") as f: f.write(resp.content) return output_path ``` ### Technical Analysis The publicly documented `download_image` function performs a server-side request to an arbitrary caller-provided URL. It does not validate: - The URL scheme or destination hostname. - Whether DNS resolution produces a loopback, private, link-local, multicast, or reserved IP address. - Redirect destinations. - The response content type or actual file format. - The maximum response size. - Whether `output_path` is confined to an approved output directory. Consequently, a caller that controls `image_url` can direct the Agent host to request internal or otherwise non-public HTTP services. Redirects followed automatically by `requests` can also lead the request to a prohibited destination. The 60-second timeout limits request duration but not response size. Accessing `resp.content` buffers the complete response in memory before writing it, allowing a large response to consume substantial memory and disk capacity. The same helper is also used for URLs returned by the MiniMax image-generation API. Those URLs cross a remote trust boundary and should not be treated as inherently safe without destination and response validation. ### Attack Path 1. An attacker or untrusted workflow supplies a URL to the documented `download_image` function, or causes a remote API response to contain a hostile download URL. 2. The URL points directly to an internal endpoint, cloud metadata service, loopback service, or an external endpoint that redirects to one. 3. `requests.get()` issues ...[truncated 1315 chars]
- Remediation
- ## Remediation Suggestions 1. Permit only `https` URLs and reject URLs containing embedded credentials or unsupported schemes. 2. Resolve the hostname before connecting and reject every loopback, private, link-local, multicast, unspecified, and reserved IPv4 or IPv6 address. 3. Prevent DNS rebinding by connecting only to the validated address while preserving correct TLS hostname verification, or use a hardened outbound proxy. 4. Disable redirects, or validate the scheme, hostname, and resolved addresses at every redirect hop. 5. Prefer an explicit allowlist of trusted image-delivery domains. If only MiniMax-generated images should be downloaded, document and enforce the expected MiniMax/CDN hosts. 6. Use `stream=True` and enforce a strict maximum byte count before and during download rather than accessing `resp.content`. 7. Validate the response `Content-Type`, then inspect file signatures and decode the image with a safe image library before accepting it. 8. Constrain output files to a dedicated directory. Resolve the final path and verify that it remains beneath that directory; reject traversal and unsafe symlink targets. 9. Use exclusive file creation or an explicit overwrite policy to prevent unintended replacement of existing files. 10. Apply outbound firewall rules that block metadata, loopback, link-local, and private network ranges as defense in depth.
