Open WebUI SSRF via HTTP Redirect Bypass of validate_url() (CVE-2026-45401)
by nayakchinmohan · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-45401
- Category
- web
- Affected product
- Open WebUI
- Affected versions
- v0.9.4 (per source repository)
- Disclosed
- 2026-07-05
- Patch status
- unpatched
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-07 |
| Author / Researcher | nayakchinmohan |
| CVE / Advisory | CVE-2026-45401 |
| Category | web |
| Severity | High |
| CVSS Score | Not specified in source |
| Status | PoC |
| Tags | ssrf, open-webui, redirect-bypass, url-validation-bypass, internal-network-access |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Open WebUI |
| Versions Affected | v0.9.4 (per source repository) |
| Language / Platform | Bash (PoC), targeting a Python/aiohttp backend |
| Authentication Required | Yes (regular user-role account, non-admin) |
| Network Access Required | Yes |
Summary
Open WebUI v0.9.4 validates user-supplied URLs with a validate_url() function before the server fetches them, intended to block requests to internal/private hosts. However, the validation only checks the initial hostname supplied by the client; when the server-side HTTP client (requests or aiohttp) follows a subsequent HTTP redirect (302), it will happily fetch whatever internal target the redirect points to. This PoC demonstrates two independent vectors — the web-retrieval ingestion endpoint and the chat-completion image_url feature — both of which perform server-side requests that can be redirected to internal/private network resources, resulting in classic SSRF.
Vulnerability Details
Root Cause
validate_url() inspects only the hostname of the URL provided directly by the client. It does not re-validate the destination of HTTP redirects that the underlying HTTP client (requests.get() for the retrieval endpoint, aiohttp.ClientSession.get() for the image-fetch path) transparently follows. An attacker-controlled public URL can therefore respond with a 302 redirect to an internal address (e.g. http://169.254.169.254/, http://127.0.0.1:PORT/, or other internal services), and the server will fetch it as if it were the original public URL.
Attack Vector
- Attacker stands up a public redirect server (
redirect_server.py, not included in this repo) that responds with an HTTP 302 to an internal/private target of the attacker’s choosing. - Attacker authenticates to Open WebUI as a regular (non-admin) user and obtains a
USER_TOKEN(JWT). - Vector A — Attacker sends
POST /api/v1/retrieval/process/web?process=falsewith{"url": "<REDIRECT_URL>"}.validate_url()sees the public redirect URL and passes it; the server’srequests.get()call then follows the 302 to the internal target and returns/ingests its full response body (useful for binary/full-content exfiltration). - Vector B — Attacker sends
POST /api/chat/completionswith a chat message containing animage_urlcontent block pointing at<REDIRECT_URL>.convert_url_images_to_base64()→get_image_base64_from_url()usesaiohttpto fetch the URL, again following the redirect to the internal target; the fetched body is base64-encoded and injected into the LLM prompt context (semi-blind, but content may be reflected back in the model’s response). - Attacker inspects the redirect server logs and/or the API responses to confirm the request originated from the Open WebUI server (not the attacker), proving successful SSRF against the internal target.
Impact
A low-privileged, authenticated (non-admin) user can coerce the Open WebUI server into making arbitrary HTTP requests to internal-only network resources (cloud metadata endpoints, internal admin panels, other services on the internal network, etc.), potentially leading to credential/metadata theft, internal service enumeration, or further pivoting — all while bypassing the intended validate_url() SSRF protection via a simple redirect.
Environment / Lab Setup
Target: Open WebUI v0.9.4, default configuration, running on http://target:3000
Attacker tooling:
- A regular (non-admin) Open WebUI user account and its JWT (USER_TOKEN)
- A publicly reachable redirect server (e.g. a small Python script serving
HTTP 302 responses toward the desired internal target), referenced as
REDIRECT_URL in the PoC
- curl, python3 (for pretty-printing JSON responses)
Proof of Concept
PoC Script
See
exploit_ssrf.shin this folder.
| |
Running the script fires both SSRF vectors (the retrieval/web-ingestion endpoint and the chat-completion image_url endpoint) against the target and prints the raw JSON/response bodies; a hit on the attacker’s redirect server logs originating from the Open WebUI server’s IP confirms server-side fetch of the internal target.
Detection & Indicators of Compromise
- Outbound HTTP requests from the Open WebUI application server to external
"redirect" hosts followed immediately by a second connection to internal
IP ranges (RFC1918, 169.254.169.254, etc.) shortly after.
- Server-side HTTP client logs showing 3xx redirect responses being followed
automatically for /api/v1/retrieval/process/web and /api/chat/completions
requests.
- Unexpected requests to internal-only endpoints or cloud metadata services
appearing to originate from the Open WebUI host.
Signs of compromise:
- Non-admin user accounts issuing retrieval or chat-completion requests referencing external “redirector” style URLs.
- Internal services or metadata endpoints receiving requests sourced from the Open WebUI server’s IP with no legitimate business reason.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Re-validate the final destination host/IP after every redirect hop (or disable automatic redirect following and manually validate each hop) in both the retrieval web-ingestion path and the image-fetch path before performing the request. |
| Interim mitigation | Disable/restrict the web-retrieval and image_url ingestion features for non-admin users, or place an egress proxy/firewall in front of the Open WebUI server that blocks outbound connections to private/internal IP ranges regardless of redirect chains. |
References
Notes
Mirrored from https://github.com/nayakchinmohan/CVE-2026-45401 on 2026-07-05.
| |