Skip to main content

Open WebUI CVE-2026-45665

| EUVDEUVD-2026-30664 HIGH
Cross-site Scripting (XSS) (CWE-79)
2026-05-14 https://github.com/open-webui/open-webui GHSA-cqp4-qqvg-3787
8.1
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
8.1 HIGH
AV:N/AC:L/PR:H/UI:R/S:C/C:H/I:H/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

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

Lifecycle Timeline

3
Source Code Evidence Fetched
May 14, 2026 - 22:04 vuln.today
Analysis Generated
May 14, 2026 - 22:04 vuln.today
CVE Published
May 14, 2026 - 20:27 nvd
HIGH 8.1

DescriptionGitHub Advisory

Summary

A Stored Cross-Site Scripting (XSS) vulnerability exists in the Banner component due to an improper sanitization order (specifically, DOMPurify is executed before the marked library).

This vulnerability allows a compromised or malicious administrator to plant a malicious payload in the global banner. Crucially, this vector enables Privilege Escalation, as the malicious banner is rendered for all users, including the Super Admin (Primary Admin).

Consequently, the payload successfully bypasses the existing security mechanism. An attacker can leverage this to steal the Super Admin's session token

Details

Root Cause: The code attempts to sanitize the input using DOMPurify.sanitize() before parsing it with marked.parse().

DOMPurify cleans the raw input. Since [Link](javascript:alert(javascript:alert(localStorage.token))) is valid text (not HTML), it passes through DOMPurify unchanged. marked handles the text and converts it into a clickable HTML link: <a href="javascript:alert(javascript:alert(localStorage.token))">Link</a>. This resulting unsafe HTML is rendered directly via {@html ...} without further checks.

src/lib/components/common/Banner.svelte (Line 103)

svelte
{@html marked.parse(DOMPurify.sanitize((banner?.content ?? '').replace(/\n/g, '<br>')))}

POC

  1. Attacker Action: Log in as a compromised Admin account and navigate to Settings > Interface > UI > Banners.
  2. Injection: Add a new banner and enter the following payload in the content field. This payload creates a link that alerts the user's session token when clicked.
markdown
    [Click for Security Update](javascript:alert(localStorage.token))
  1. Execution: Click Save. The malicious banner is now stored and active.
  2. Victim Action (Privilege Escalation): The Primary Admin logs in and sees the banner on the main dashboard. Believing it to be a system notification, they click the link.

Victim Dashboard View:

<img width="880" height="245" alt="image" src="https://github.com/user-attachments/assets/b70d7f65-ab34-4634-9e78-2a8a7eda1439" />

  1. Result: The JavaScript executes immediately within the Primary Admin's session, exposing their full-access token.

Impact

Extend permissions and damage to the entire system. You need administrator privileges to create banners, but this vulnerability is important because it can attack primary administrators and other administrators.

Destination: Other Administrators /Primary Administrators. Attack Vector: Corrupting all administrator accounts (even those with limited scope if future granular privileges exist or simply credentials are compromised) could allow an attacker to set traps for the default administrator. The result: Unlike self-XSS or simple administrator configuration changes, this allows you to capture active sessions for the most privileged users and bypass authentication controls such as MFA (because the session is already active).

Recommended Patch

Modify src/lib/components/common/Banner.svelte (Line 103):

{@html DOMPurify.sanitize(marked.parse((banner?.content ?? '').replace(/\n/g, '<br>')))}

Resolution

Fixed in v0.8.0. src/lib/components/common/Banner.svelte:103 now applies the sanitization in the correct order: DOMPurify.sanitize(marked.parse(...)). marked.parse runs first and converts [text](javascript:...) markdown into the corresponding HTML link element; DOMPurify.sanitize then strips the javascript: URL and any other dangerous attributes/elements before the result reaches {@html ...}.

Users on >= 0.8.0 are not affected.

AnalysisAI

Stored XSS in Open WebUI Banner component enables privilege escalation from compromised admin to Super Admin. A malicious administrator can inject markdown-based JavaScript payloads (e.g., [text](javascript:...)) that bypass DOMPurify sanitization due to incorrect sanitizer-parser execution order in Banner.svelte:103. When the Super Admin views the global banner and clicks the crafted link, their session token is exfiltrated to the attacker. Vendor-released patch available in v0.8.0 (2026-02-12) reversing sanitization order to DOMPurify.sanitize(marked.parse(...)). CVSS 8.1 (High) with Network vector, Low complexity, but requires High privileges (admin) and User interaction (click). No KEV listing or EPSS data available; publicly disclosed POC with detailed reproduction steps.

Technical ContextAI

Open WebUI is a web-based UI for LLM interactions, built with Svelte framework and distributed as an npm package. The vulnerability resides in the Banner component (src/lib/components/common/Banner.svelte:103) which renders administrator-configured global banners visible to all users. The root cause is an incorrect sanitization pipeline: {@html marked.parse(DOMPurify.sanitize(...))}. DOMPurify (an HTML sanitizer) executes first on raw markdown text, where [Link](javascript:alert()) appears benign (plain text, not HTML). The unsanitized markdown then passes to marked.parse() which converts it into HTML <a href="javascript:alert()">Link</a>. This dangerous HTML is rendered via Svelte's {@html} directive without further checks. Per CWE-79 (Improper Neutralization of Input During Web Page Generation), the flaw is exacerbated by processing order-sanitization must occur after markup parsing, not before. The affected package is pkg:npm/open-webui versions <= 0.7.2.

RemediationAI

Upgrade to Open WebUI v0.8.0 or later immediately (released 2026-02-12), available at https://github.com/open-webui/open-webui/releases/tag/v0.8.0. Version 0.8.0 fixes the vulnerability by reversing sanitization order to DOMPurify.sanitize(marked.parse(...)) in Banner.svelte:103, ensuring markdown is parsed to HTML before dangerous elements/attributes are stripped. WARNING: v0.8.0 includes database schema migrations requiring downtime-backup database before upgrading and avoid rolling updates in multi-server deployments per release notes. If immediate upgrade is not feasible, implement compensating controls: (1) Disable global banner feature entirely via application config or UI if business impact is acceptable; (2) Audit all existing banners for javascript:, data:, and vbscript: URL schemes and remove suspicious content; (3) Restrict banner modification permissions to only the Primary Admin account via role-based access control, eliminating lateral privilege escalation vector (trade-off: does not prevent compromised Primary Admin from self-attack); (4) Deploy Content Security Policy header default-src 'self'; script-src 'self' to block inline JavaScript execution from javascript: URLs (trade-off: may break legitimate application features relying on inline scripts). Monitor admin access logs for unauthorized banner modifications during interim period.

Share

CVE-2026-45665 vulnerability details – vuln.today

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