Sep 10, 2026·7 min read·21 visits
An SSRF vulnerability in Open WebUI allows authenticated attackers to bypass network access controls and fetch internal resources or cloud metadata via crafted redirects and direct IP literals.
Server-Side Request Forgery (SSRF) vulnerability in Open WebUI (v0.9.5 to v0.11.1) allows authenticated users to bypass private IP and host filter lists by abusing HTTP redirect handling or using IP literals with the aiohttp client.
Open WebUI is an extensible, self-hosted user interface designed to interact with Large Language Models (LLMs). The platform offers features that require outbound network communication, including Retrieval-Augmented Generation (RAG), web scraping, web search integration, and processing of user-supplied URLs. These actions expose an attack surface where the application acts as an HTTP client executing server-side requests based on user input.
To manage this risk, the application integrates validation controls that inspect outbound request destinations. These validation mechanisms check target hostnames and IPs against blocklists and look up destination addresses to block loopback (e.g., 127.0.0.1, [::1]) and private (RFC 1918) IP networks. If these checks are bypassed, the server can be forced to communicate with internal resources.
This vulnerability, tracked as CVE-2026-88001, is a Server-Side Request Forgery (SSRF) classified under CWE-918. In versions ranging from v0.9.5 up to v0.11.1, authenticated users can exploit validation logic gaps to bypass both host filtering (WEB_FETCH_FILTER_LIST) and private network restrictions. The security control failure occurs because the backend does not re-validate destination targets when following HTTP redirects and fails to intercept IP-literal connections in the aiohttp library.
The vulnerability stems from two independent flaws in the network fetch layer. The first flaw is the lack of redirect verification. The validation function validate_url() is applied only to the initial URL provided by the user. Once the initial check succeeds, the application passes the URL to the HTTP client (requests or aiohttp) with redirect-following enabled. When an external host responds with a 302 Found status and a Location header pointing to an internal resource, the client follows the redirect without applying validation checks on the subsequent target.
The second flaw is specific to the aiohttp client. Open WebUI attempted to block private IP addresses by defining a custom DNS resolver class named _SSRFSafeResolver. This resolver intercepted host name lookups and validated the returned IP addresses. However, modern HTTP clients contain optimizations that identify direct IP literals, such as 127.0.0.1 or 169.254.169.254, and skip standard DNS resolution entirely.
Because the DNS resolution process is bypassed when resolving IP literals, the custom _SSRFSafeResolver is never executed for these targets. Consequently, an attacker can supply a redirect pointing directly to an IP address literal, allowing the client to establish a TCP connection to the loopback or private network without triggering any of the safety checks.
The patch in commit e3e4bd87df6fc629e7e22081d980d55a7632b8b7 remediates both gaps by moving the validation checks from the pre-flight parser and DNS resolver down to the socket connection and transport layer.
For aiohttp, the validation logic is refactored out of the resolver and placed within a custom TCPConnector subclass named _SSRFSafeConnector. This class overrides the connect and _resolve_host methods:
class _SSRFSafeConnector(aiohttp.TCPConnector):
"""Rejects filter-listed request targets, and non-global IPs on each new connection."""
async def connect(self, req, traces, timeout):
# Check host before connection is established
_assert_host_allowed(req.url.host)
return await super().connect(req, traces, timeout)
async def _resolve_host(self, host, port, traces=None):
# Capture IP literals that bypass DNS resolvers
results = await super()._resolve_host(host, port, traces=traces)
_assert_addresses_allowed([entry['host'] for entry in results])
return resultsFor the synchronous requests library, the patch introduces a transport adapter (_SSRFSafeAdapter) that hooks into HTTPAdapter. The send method is executed for every redirection step in the request lifecycle, ensuring each redirect target is validated:
class _SSRFSafeAdapter(HTTPAdapter):
"""requests adapter that rejects filter-listed request targets and non-global IPs at connect time."""
def init_poolmanager(self, *args, **kwargs):
super().init_poolmanager(*args, **kwargs)
self.poolmanager.pool_classes_by_scheme = {
'http': _SafeHTTPPool,
'https': _SafeHTTPSPool,
}
def send(self, request, *args, **kwargs):
# Validate host for initial request and all redirect hops
_assert_host_allowed(urllib.parse.urlparse(request.url).hostname)
return super().send(request, *args, **kwargs)Additionally, the patch addresses complex IP parsing evasions. Attackers often attempt to bypass validation filters using IPv6-mapped IPv4 addresses (e.g., [::ffff:127.0.0.1]). The patch implements an active un-mapping function _embedded_ipv4 to extract the underlying IPv4 address from various transition encodings (SIIT, 6to4, Teredo, and NAT64) and match them against the restricted private IP ranges.
An exploit scenario begins with an authenticated attacker setting up an external HTTP server that acts as a redirect agent. The attacker configures this external server to respond with a redirect to the target local address or cloud metadata endpoint, such as http://169.254.169.254/computeMetadata/v1/.
The attacker then uses an authorized feature within Open WebUI, such as adding a new web page source to the document ingestion pipeline or triggering an automated web search. The input provided to the application is the URL of the attacker's external server.
Because the destination check passes on attacker.com during the pre-flight phase, Open WebUI proceeds to execute the HTTP request. Upon receiving the 302 Found response, the underlying client automatically requests the location specified in the header. The application does not check the redirect destination, allowing the client to fetch data from the internal network and return the payload to the attacker's interface.
The primary impact of this SSRF is unauthorized information disclosure from the server's local environment. An attacker with standard user credentials can map internal networks, scan local ports, and discover active services. If Open WebUI is hosted on a cloud instance, the vulnerability allows the retrieval of cloud metadata, which frequently contains highly sensitive information such as access tokens, IAM credentials, and instance configurations.
The CVSS v3.1 base score is 5.0, reflecting a Medium severity impact. The attack requires low privileges, has low complexity, and does not require user interaction. The Scope metric is set to Changed ('C') because the vulnerability allows an attacker to pivot from the Open WebUI web application container into the secondary system of the internal host or metadata services.
While there is no integrity or availability impact, the confidentiality impact is significant when deployed in multi-tenant environments or cloud infrastructure where local endpoints contain operational keys or configuration details. This makes the vulnerability an attractive tool for initial reconnaissance and cloud-pivoting strategies.
The complete remediation of this issue requires upgrading Open WebUI to version v0.11.1 or above. This release integrates socket-level and connection-level safety adaptors, ensuring every destination in a redirection chain is inspected before data is transferred.
However, a critical architectural dependency exists for deployments running behind a forward proxy. When Open WebUI is configured to route all outbound requests through an upstream forward proxy (such as Squid or an enterprise egress gateway), the connection-level socket checks in _SSRFSafeConnector and _SSRFSafeAdapter will only observe the IP address of the proxy server.
Because the destination IP lookups are delegated to the proxy, the internal connection-level validation cannot verify the actual target destination. In such environments, administrators must implement egress firewall rules and host filters directly on the forward proxy server. This defense-in-depth approach ensures that the proxy rejects requests targeting local IP networks, loopback interfaces, or restricted cloud endpoints.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
open-webui open-webui | >= 0.9.5, < 0.11.1 | v0.11.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 5.0 |
| Impact | Low Confidentiality / Information Disclosure |
| Exploit Status | Proof of Concept (PoC) |
| CISA KEV Status | Not Listed |
| Ransomware Use | No Known Association |
The web application receives a URL or similar vector from an upstream source and retrieves the contents of this URL without verifying the destination belongs to an allowed host or IP range.
CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.
An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.
CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.
CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.
CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.
CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.