Skip to main content

Open WebUI EUVDEUVD-2026-38525

| CVE-2026-54018 HIGH
Server-Side Request Forgery (SSRF) (CWE-918)
2026-06-17 https://github.com/open-webui/open-webui GHSA-jrfp-m64g-pcwv
7.7
CVSS 3.1 · Vendor: https://github.com/open-webui/open-webui
Share

Severity by source

Vendor (https://github.com/open-webui/open-webui) PRIMARY
7.7 HIGH
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
vuln.today AI
8.5 HIGH

Network-reachable feature requires a low-priv authenticated user (PR:L), no UI; SSRF crosses scope to internal services (S:C) with high confidentiality impact (IMDS creds) and low integrity from possible internal write requests.

3.1 AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:L/VI:N/VA:N/SC:H/SI:L/SA:N

Primary rating from Vendor (https://github.com/open-webui/open-webui).

CVSS VectorVendor: https://github.com/open-webui/open-webui

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
None
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
Jun 18, 2026 - 01:34 vuln.today
Analysis Generated
Jun 18, 2026 - 01:34 vuln.today
CVE Published
Jun 17, 2026 - 17:55 github-advisory
HIGH 7.7

DescriptionCVE.org

Summary

The SafePlaywrightURLLoader implements a validate_url function to prevent SSRF attacks by checking the IP address of the user-provided URL. However, this validation is performed only on the initial URL.

Since Playwright automatically follows HTTP redirects (301/302) by default, an attacker can bypass the validation by providing a safe URL that redirects to a restricted internal network address (e.g., localhost, Docker container network, or Cloud Metadata).

This allows the application to access internal services despite ENABLE_RAG_LOCAL_WEB_FETCH being set to False

Details

Root Cause

The application validates the initial user-provided URL using self._safe_process_url_sync(url). This correctly resolves the domain and ensures it does not point to a private IP.

The application then calls page.goto(url). By default, Playwright automatically follows HTTP redirects (301/302).

The Bypass: If the destination server returns a redirect to an internal IP (e.g., 127.0.0.1 or 169.254.169.254), the browser follows it without re-validating the new destination. The initial validation is bypassed because it only checked the first URL, not the entire redirect chain.

python
for url in self.urls:
    try:
        self._safe_process_url_sync(url)
        page = browser.new_page()
        response = page.goto(url, timeout=self.playwright_timeout)  #this
        if response is None:
            raise ValueError(...)
        text = self.evaluator.evaluate(page, browser, response)

PoC

(This PoC uses Docker to easily demonstrate internal network access (accessing a container by service name). However, the vulnerability is NOT tied to Docker.)

  1. Ensure the Open WebUI is configured with the following environment variables. The vulnerability is specific to the Playwright engine.
  2. ENABLE_RAG_LOCAL_WEB_FETCH=False (Default)
  3. RAG_WEB_LOADER_ENGINE=playwright
  4. Setup and run attack server
  5. In Open WebUI, use the "Web Search" or "URL Loader" feature.
  6. Input the attacker's URL (e.g., http://attacker-ip/).
python
# attack_server.py
from flask import Flask, redirect
app = Flask(__name__)

@app.route('/')
def attack():
# Redirect to the Open WebUI container's internal port
    return redirect("http://open-webui:8080/api/version", code=302)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

<img width="580" height="192" alt="image" src="https://github.com/user-attachments/assets/4600dbb5-a81d-4e58-b787-afe04fe59d6e" />

The Playwright browser follows the redirect to the internal address (http://open-webui:8080/api/version)

Impact

+ Cloud Environments: Access to Instance Metadata Service (IMDS) to steal cloud credentials. + Intranet/On-Premise: Scanning internal networks and accessing unauthenticated internal tools. + Container Environments: Accessing other containers within the same network.

Recommended Patch

implement a request interceptor using Playwright's page.route. This ensures all requests, including redirects, are validated before connection.

apply the following logic to both lazy_load and alazy_load methods:

python
# async context
async def intercept_route(route):
    try:
        await run_in_threadpool(validate_url, route.request.url)
        await route.continue_()
    except Exception:
        await route.abort()

await page.route("**/*", intercept_route)
response = await page.goto(url, timeout=self.playwright_timeout)

AnalysisAI

SSRF protection bypass in Open WebUI's SafePlaywrightURLLoader (versions <= 0.9.5) allows authenticated users to access internal network resources by supplying an externally-hosted URL that returns an HTTP 301/302 redirect to a private address. Because Playwright's page.goto() automatically follows redirects without re-validating the destination, attackers can reach localhost, container-network peers, or cloud metadata endpoints (169.254.169.254) even when ENABLE_RAG_LOCAL_WEB_FETCH=False. A working PoC is published in the GHSA advisory; there is no public exploit identified at time of analysis being actively used, and no CISA KEV listing.

Technical ContextAI

Open WebUI is a self-hosted Python web interface for LLM backends distributed via pip. Its Retrieval-Augmented Generation (RAG) feature lets users submit URLs to be fetched and indexed; the SafePlaywrightURLLoader is one of several configurable web-loader engines (selected via RAG_WEB_LOADER_ENGINE=playwright) and uses the Playwright headless-browser library to render JavaScript-heavy pages. The flaw is a classic CWE-918 (Server-Side Request Forgery) instance caused by Time-of-Check / Time-of-Use divergence: _safe_process_url_sync() resolves and validates only the user-supplied URL against a private-IP denylist, but the subsequent page.goto() call uses Playwright's default behavior of transparently following HTTP 3xx redirects, so a 302 from an attacker-controlled host pointing at 127.0.0.1, an internal container DNS name, or the cloud IMDS endpoint is fetched without revalidation. The recommended fix uses Playwright's page.route('**/*', interceptor) hook to re-run validate_url on every individual request the browser issues, including redirects.

RemediationAI

Vendor-released patch: upgrade open-webui to 0.9.6 or later, which adds a Playwright page.route('**/*', ...) interceptor that re-runs validate_url for every request including redirects (see https://github.com/open-webui/open-webui/security/advisories/GHSA-jrfp-m64g-pcwv). If immediate upgrade is not possible, switch RAG_WEB_LOADER_ENGINE to a non-Playwright loader (e.g., the requests-based engine) which is not affected by this redirect-follow behavior, accepting the trade-off of losing JavaScript rendering for fetched pages. As compensating controls, restrict outbound egress from the Open WebUI container/VM via network policy or an egress proxy to block traffic to RFC1918 ranges, 127.0.0.0/8, and 169.254.169.254, force IMDSv2 on AWS hosts to require a session token the browser will not send, and limit Web Search / URL Loader use to trusted accounts via Open WebUI's RBAC; these mitigations reduce blast radius but do not close the SSRF in-process and may break legitimate internal-knowledge-base integrations.

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

EUVD-2026-38525 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy