T09 · Insecure Skill Coding Practices
- Location
scripts/gen.py:35- Finding
Unrestricted Download of Model-Provided URLs Enables Server-Side Request Forgery
- Content
View full analysis
str: parsed = urlparse(url) ext = os.path.splitext(parsed.path)[1].lstrip(".") or "png" filename = f"openrouter_image_{int(time.time())}_{idx}.{ext}" path = os.path.join(out_dir, filename) r = requests.get(url, timeout=60) r.raise_for_status() with open(path, "wb") as f: f.write(r.content) return path ``` URLs are collected from multiple fields in the remote model response, including arbitrary URLs embedded in textual content: ```python elif isinstance(content, str): if "data:image/" in content: for token in content.split(): if token.startswith("data:image/"): urls.append(token) if "http://" in content or "https://" in content: for token in content.split(): if token.startswith("http://") or token.startswith("https://"): urls.append(token) ``` Every extracted non-data URL is then downloaded: ```python paths = [] for i, u in enumerate(urls): if u.startswith("data:image/"): paths.append(_save_data_url(u, out_dir, i)) else: paths.append(_download_url(u, out_dir, i)) return paths ``` ### Technical Analysis The script treats URLs supplied by the OpenRouter/model response as trusted and passes them directly to `requests.get()`. It does not enforce HTTPS, restrict destinations to approved image-hosting domains, validate resolved IP addresses, or reject loopback, private, link-local, reserved, and cloud metadata address ranges. Redirect destinations are also not validated. Consequently, a malicious or prompt-influenced model response containing a URL such as ...[truncated 3047 chars]- Remediation
View remediation
