khoj has an unauthenticated path traversal in /home/ endpoint that allows file read from server filesystem
### 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 `FileResponse` does 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/passwd ``` ### PoC ```bash # Read /etc/passwd (no authentication required) curl http://localhost:42110/home/../../../../../../../etc/passwd # Read applica
GHSA-62mm-xwmv-crhg
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:GHSA-62mm-xwmv-crhg
khoj
Source reference: /affected/0/package/name
- Affected versions
- 2.0.0b23
Source reference:
/affected/0/versions2.0.0b24Source reference:
/affected/0/versions2.0.0b24.dev1Source reference:
/affected/0/versions2.0.0b24.dev4Source reference:
/affected/0/versions2.0.0b25.dev1Source reference:
/affected/0/versions2.0.0b25.dev10Source reference:
/affected/0/versions2.0.0b25.dev3Source reference:
/affected/0/versions2.0.0b25.dev7Source reference:
/affected/0/versions2.0.0b25.dev9Source reference:
/affected/0/versions - Fixed versions
- 2.0.0-beta.25
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "2.0.0-beta.23"
},
{
"fixed": "2.0.0-beta.25"
}
]
}
],
"package": {
"name": "khoj",
"purl": "pkg:pypi/khoj",
"ecosystem": "PyPI"
},
"versions": [
"2.0.0b23",
"2.0.0b24",
"2.0.0b24.dev1",
"2.0.0b24.dev4",
"2.0.0b25.dev1",
"2.0.0b25.dev10",
"2.0.0b25.dev3",
"2.0.0b25.dev7",
"2.0.0b25.dev9"
],
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-62mm-xwmv-crhg/GHSA-62mm-xwmv-crhg.json"
}
}
]Publisher severity
high
Source reference: /database_specific/severity
- Event
- #18217 · Revision 1
- Added to Heist Feed
- Publisher date