Sep 23, 2026·5 min read·3 visits
Unauthenticated remote timing side-channels in HKUDS LightRAG authentication logic permit username enumeration and plaintext password recovery.
HKUDS LightRAG prior to version 1.5.5 is vulnerable to multiple timing side-channels (CWE-208) in its API authentication layer. The password verification logic in `lightrag/api/passwords.py` compares plaintext administrative credentials using Python's short-circuiting equality operator (`==`). Additionally, `lightrag/api/auth.py` terminates authentication early on non-existent usernames, creating an observable latency difference compared to computationally expensive bcrypt comparisons on valid accounts. Together, these allow remote unauthenticated attackers with low-latency network access to enumerate valid usernames and extract plaintext passwords character by character.
HKUDS LightRAG is an open-source framework designed for fast, retrieval-augmented generation (RAG) using large language models. To restrict access to administrative functions, the application exposes API endpoints protected by basic token authentication. The credentials are defined using the AUTH_ACCOUNTS configuration parameter.
Prior to version 1.5.5, the authentication mechanism exposed two major security weaknesses. The primary weakness (CWE-208) resides in the password verification routines, which compare plaintext administrative password strings without a constant-time algorithm. A secondary weakness allows an external attacker to reliably determine valid usernames by analyzing the processing time of authentication requests, bypass the primary layer, and recover plaintext credentials.
The vulnerability stems from two independent implementation details within the authentication layer. First, lightrag/api/passwords.py relies on Python's default equality operator (==) to match supplied passwords against stored plaintext values.
Python's string and byte equality checks optimize comparison performance using two techniques:
False immediately.False.Because of this short-circuiting behavior, the execution latency is directly proportional to the number of matching characters in the user's input. A guess that matches the first three characters of a password will take slightly longer to fail than a guess that mismatch on the first character.
Second, the authentication handler in lightrag/api/auth.py evaluates whether the user exists prior to executing password checking. When bcrypt hashing is enabled, verifying a valid user triggers bcrypt.checkpw, which executes in roughly 100 milliseconds. If the username does not exist, the routine returns False immediately in microseconds. This large difference in latency allows external observers to enumerate valid usernames.
In the vulnerable version of the codebase, password verification was implemented as a direct equality operation:
# Vulnerable implementation in lightrag/api/passwords.py
def verify_password(plain_password: str, stored_password: str) -> bool:
# ...
return stored_password == plain_passwordThis behavior is fixed in the patch by utilizing Python's hmac.compare_digest function. The corrected implementation enforces constant-time byte comparisons by processing the full length of the byte strings:
# Patched implementation in lightrag/api/passwords.py
import hmac
def verify_password(plain_password: str, stored_password: str) -> bool:
# ...
return hmac.compare_digest(
stored_password.encode("utf-8"), plain_password.encode("utf-8")
)Additionally, the username enumeration side-channel was resolved in lightrag/api/auth.py by integrating a dummy verification mechanism. If a username does not exist in the store, the application executes a verification pass against a static, synthetic bcrypt hash (_DUMMY_VERIFY_SPEC). This forces the server to spend identical computational time on invalid accounts:
# Patched implementation in lightrag/api/auth.py
_DUMMY_VERIFY_SPEC = (
BCRYPT_PASSWORD_PREFIX
+ "$2b$12$ilI0sY2jGfy4h0AVtn6WuutU6BFwzZq5MVvrQYY9fbyQ59NI2NBKa"
)
def verify_password(self, username: str, plain_password: str) -> bool:
stored_password = self.accounts.get(username)
if stored_password is None:
# Execute dummy verification to equalize execution time
verify_password(plain_password, _DUMMY_VERIFY_SPEC)
return False
return verify_password(plain_password, stored_password)To exploit these vulnerabilities, an attacker needs a network path with minimal jitter, such as co-location inside the same cloud region or container infrastructure. The attack is carried out in two distinct phases:
An attacker sends repetitive requests containing different candidate usernames to the /login endpoint. By sorting the returned network latencies, usernames that delay response times by roughly 100 milliseconds are marked as valid administrative accounts on systems configured with bcrypt.
Once a username is validated, the attacker attacks the plaintext comparison routine:
admin123 and the attacker sends aaaa, it fails immediately at index 0. Sending axxx fails at index 1, which requires slightly more time. Analyzing the latency distributions over a high number of requests isolates the correct character prefix, eventually reconstructing the credential.A successful attack compromises the confidentiality of administrative credentials for the LightRAG framework. This vulnerability possesses a CVSS 3.1 rating of 5.9 (Medium) with the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N.
The attack complexity is designated as High (AC:H) because measuring sub-millisecond differences over a network requires precise statistical analysis, filtering algorithms, and low network latency. However, in containerized or shared network architectures, these requirements are met. Compromise of administrative passwords grants attackers write and read capabilities over the retrieval-augmented generation engine, including the ability to manipulate indexed documentation, execute prompt injections, and poison generative AI outputs.
The primary resolution is to upgrade HKUDS LightRAG to version 1.5.5 or higher, which integrates the constant-time comparisons and the dummy bcrypt executions.
Additionally, administrators must configure their deployment's passwords securely. When storing accounts in the AUTH_ACCOUNTS configurations, passwords must be formatted using cryptographic bcrypt hashes prefixed with the {bcrypt} tag. Plaintext values are discouraged, as any deployment storing unhashed passwords remains vulnerable to local configuration leakage and other password-recovery mechanisms.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
LightRAG HKUDS | < 1.5.5 | 1.5.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-208: Observable Timing Discrepancy |
| Attack Vector | Network (Low-latency / High-precision) |
| CVSS v3.1 | 5.9 (Medium) |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
| Impact | Administrative Credential Recovery & Username Enumeration |
The product performs an operation that takes a variable amount of time, and the security of the operation is dependent on that operation being completed in a constant amount of time.
CVE-2026-85709 is a sensitive information exposure vulnerability in HKUDS LightRAG prior to version 1.5.5. The vulnerability allows remote, unauthenticated clients to trigger server-side errors and receive raw Python exception details, including local filesystem paths, database connection strings, credentials, and internal system configurations.
LightRAG prior to version 1.5.5 does not implement rate limiting, lockout mechanisms, or throttling on its `/login` authentication endpoint. This allows unauthenticated remote attackers to perform rapid brute-force attacks to crack passwords and hijack active sessions. Furthermore, because the endpoint processed synchronous bcrypt verifications inside an asynchronous event loop, concurrent brute-force requests can easily exhaust server CPU resources, triggering an unauthenticated Denial of Service (DoS).
A security vulnerability in HKUDS/LightRAG prior to v1.5.5 allows authenticated attackers to bypass the native markdown image downloader guard. The system fails to normalize IPv6 transition wrappers (such as NAT64, IPv4-compatible, and 6to4 blocks) encapsulating internal IPv4 addresses. Python's ipaddress library evaluates these wrappers as globally routable, but hosting environments running NAT64/DNS64 routing decapsulate and route the requests to internal resources.
HKUDS LightRAG, an open-source retrieval-augmented generation (RAG) framework, is vulnerable to Stored Cross-Site Scripting (XSS) in its WebUI chat rendering component prior to version 1.5.5. Unsanitized document content ingested into the vector database can propagate through the LLM response pipeline and execute malicious HTML or active JavaScript payloads inside the administrator's WebUI session. Because the application stores sensitive access keys in browser storage, successful exploitation allows complete API token extraction and administrative session hijacking.
An Insecure Direct Object Reference (IDOR) vulnerability exists in Spree open-source e-commerce solution versions 5.4.0 through 5.4.3 and 5.5.0 through 5.5.3. An authenticated attacker can predict or enumerate guest cart identifiers generated via Sqids and associate them with their own account. This unauthorized association leaks sensitive customer personally identifiable information (PII) and disrupts the checkout flow of active guest sessions.
Cloudreve before version 4.18.0 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition in its storage-quota verification logic. Authenticated attackers with basic write access can trigger multiple parallel upload sessions to bypass their storage limits, leading to host disk space exhaustion and Denial of Service.