T09 · Insecure Skill Coding Practices
- Location
scripts/generate.py:598- Finding
Provider-Controlled Image URL Enables Server-Side Request Forgery
- Content
View full analysis
bytes: headers = { **BROWSER_HEADERS, "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Referer": "https://x.ai/", } req = urllib.request.Request(url, headers=headers, method="GET") with urllib.request.urlopen(req, timeout=timeout) as r: return r.read() ``` The function is invoked using a URL supplied by the remote image provider: ```python if item.get("b64_json"): img_bytes = base64.b64decode(item["b64_json"]) elif item.get("url"): try: img_bytes = _download_image_url(item["url"]) except Exception as e: die(f"Cannot download image from {item['url']}: {e}") ``` ### Technical Analysis An OpenAI Images-compatible provider controls the `url` field returned in each response item. The application passes this value directly to `urllib.request.urlopen()` without validating: - The URL scheme. - The resolved destination address. - Whether the destination is loopback, private, link-local, reserved, or otherwise internal. - Redirect destinations. - The response size. - The response `Content-Type`. Consequently, a malicious or compromised provider can instruct the host running the Skill to make requests to destinations that are not legitimate image storage services. Potential destinations include localhost services, private network interfaces, container-management APIs, and cloud metadata endpoints. The request does not forward the provider API authorization header to the returned URL, which limits direct API-key disclosure. However, this does not prevent the provider from using the Skill as a network pivot. The response is also read into mem ...[truncated 1635 chars]- Remediation
View remediation
