T09 · Insecure Skill Coding Practices
- Location
scripts/material_searcher.py:232- Finding
Unrestricted Image Download Enables SSRF and Arbitrary File Writes
- Content
View full analysis
bool: """ Download an image. Args: image_url: Image URL save_path: Save path Returns: bool: Whether the download succeeded """ try: response = requests.get(image_url, stream=True) response.raise_for_status() with open(save_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) logger.info(f"Image downloaded: {save_path}") return True except Exception as e: logger.error(f"Image download failed: {e}") return False ``` ### Technical Analysis The `download_image` method accepts both `image_url` and `save_path` without applying security validation. `requests.get()` can connect to any URL supported by the Requests library. The method does not restrict schemes, hosts, resolved IP addresses, ports, or redirects. Consequently, an attacker who controls `image_url` can cause requests to loopback interfaces, private networks, link-local services, or cloud instance metadata endpoints. The destination is also passed directly to `open()` without constraining it to an intended media or temporary directory. Absolute paths and traversal sequences such as `../../` can therefore target any file writable by the current process. Symbolic links are not rejected. No request timeout or response-size limit is enforced. A remote server can hold the connection open or return an excessively large response. ### Attack Path 1. An attacker reaches a workflow or integration that passes untrusted URL and destination values to `download_image`. 2. The attacker supplies a URL targeting an internal service, such as a loopback administ ...[truncated 1348 chars]- Remediation
View remediation
