T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/download.py:14- Finding
Unrestricted URL Fetching Enables Server-Side Request Forgery
- Content
View full analysis
str: """Download a file from url and save to save_path. Returns the absolute path.""" os.makedirs(os.path.dirname(save_path) or ".", exist_ok=True) resp = requests.get(url, stream=True, timeout=120) resp.raise_for_status() with open(save_path, "wb") as f: for chunk in resp.iter_content(chunk_size=8192): f.write(chunk) return os.path.abspath(save_path) ``` ### Technical Analysis The application passes a caller-controlled URL directly to `requests.get()` without validating the scheme, hostname, port, or resolved IP address. It does not block loopback, link-local, private, reserved, or cloud metadata addresses. The `requests` library also follows HTTP redirects by default. Consequently, validating only the initial hostname in a future partial fix would remain insufficient: a public endpoint could redirect the request to an internal address unless every redirect destination and resolved address is validated. The request is made with the network privileges of the process running the Skill. This creates an SSRF primitive capable of reaching services that may be inaccessible from the user’s own network. ### Attack Path 1. An attacker supplies a URL targeting a loopback, private-network, link-local, or cloud metadata endpoint. Alternatively, the attacker supplies a public URL that redirects to such an endpoint. 2. The Skill passes the URL directly to `requests.get()`. 3. The Agent host connects to the destination using its own network access. 4. The endpoint’s response is written to a local file. 5. If the resulting file can be returned, read, or processed later, information exposed by the internal endpoint may become accessible outside its in ...[truncated 409 chars]- Remediation
View remediation
