VYPR
High severity7.5NVD Advisory· Published May 28, 2026

CVE-2026-32847

CVE-2026-32847

Description

DeepCode through commit c991dc2 contains a path traversal vulnerability in the SPA catch-all route in new_ui/backend/main.py that allows unauthenticated attackers to read arbitrary files by supplying percent-encoded path segments to the GET /{full_path:path} endpoint. Attackers can bypass Starlette's path normalization by encoding slashes as %2F and dots as %2E%2E, causing the joined path to traverse outside FRONTEND_DIST and exposing sensitive files such as SSH private keys, TLS certificates, and application secrets with a single HTTP request.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

DeepCode commit c991dc2 has an unauthenticated path traversal in its SPA catch-all route allowing arbitrary file read via percent-encoded path segments.

Vulnerability

The vulnerability resides in the SPA catch-all route defined in new_ui/backend/main.py (commit c991dc2, latest main as of 2026-02-09). When the environment variable DEEPCODE_ENV is set to "docker", the FastAPI server registers a GET /{full_path:path} endpoint that serves files from the FRONTEND_DIST directory. The code at lines 128–135 directly joins the user-supplied full_path parameter using Python's pathlib / operator without a containment check (is_relative_to). While Starlette normalises literal ../ sequences in URL paths, percent-encoded sequences (%2F for /, %2E%2E for ..) bypass this normalisation, allowing path traversal outside the intended directory.

Exploitation

An attacker requires only network access to the DeepCode server running in production (Docker) mode. By sending a crafted HTTP GET request to the vulnerable route with percent-encoded path traversal payloads (e.g., /%2E%2E%2F%2E%2E%2Fetc/passwd), the full_path parameter is decoded after routing, but before the path join. The joined FRONTEND_DIST / full_path traverses outside FRONTEND_DIST, enabling access to arbitrary files. No authentication or user interaction is required.

Impact

Successful exploitation allows an unauthenticated attacker to read any file the DeepCode process can access, leading to high confidentiality impact. This includes sensitive files such as SSH private keys, TLS certificates, and application secrets. The attack is executed with a single HTTP request and does not require any prior privileges.

Mitigation

As of the latest commit c991dc2 (2026-02-09), no fix has been incorporated. The maintainers have not yet released a patched version. A workaround is to implement a containment check using Path.is_relative_to(FRONTEND_DIST) before serving the file, or to deploy a reverse proxy that blocks requests containing percent-encoded traversal sequences. The CVE is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog as of its publication date [1], [2].

AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

0

No patches discovered yet.

Vulnerability mechanics

Root cause

"Missing containment check on user-supplied path joined to FRONTEND_DIST allows percent-encoded directory traversal sequences to escape the static files directory."

Attack vector

An unauthenticated attacker with network access to the DeepCode server (port 8000) sends a GET request to the catch-all SPA route `/{full_path:path}` with percent-encoded path traversal sequences. Starlette normalizes literal `../` segments during routing but does not decode percent-encoded characters before matching, so `%2F` (decoded to `/`) and `%2E%2E` (decoded to `..`) bypass normalization and reach the `full_path` parameter intact [ref_id=1]. The joined path `FRONTEND_DIST / full_path` is then resolved by the OS filesystem, allowing traversal outside the intended directory. The attacker must know the depth of `FRONTEND_DIST` from the filesystem root, which is constant across deployments and trivially determined from the project layout [ref_id=1].

Affected code

The vulnerable code is in `new_ui/backend/main.py`, inside the `IS_DOCKER` branch (lines 128–135). The catch-all route `GET /{full_path:path}` joins the user-supplied `full_path` parameter directly onto `FRONTEND_DIST` using Python's `pathlib` `/` operator with no containment check [ref_id=1].

What the fix does

No patch is published in the supplied bundle. The advisory [ref_id=1] identifies the root cause as the missing `is_relative_to` containment check on the joined path. The remediation would require validating that `file_path.resolve()` is still within `FRONTEND_DIST.resolve()` before serving the file, or using Starlette's built-in `StaticFiles` app which performs this containment check automatically [ref_id=1].

Preconditions

  • configDeepCode must be running in Docker/production mode (DEEPCODE_ENV=docker)
  • networkAttacker must have network access to the server on port 8000
  • authNo authentication required — the endpoint is reachable without credentials
  • inputAttacker must supply percent-encoded path traversal sequences (%2F for /, %2E%2E for ..) in the URL path

Reproduction

Step 1 — Start DeepCode in production mode: `git clone https://github.com/HKUDS/DeepCode.git && cd DeepCode && pip install fastapi uvicorn pydantic-settings pyyaml && mkdir -p new_ui/frontend/dist/assets && echo "<html><body>DeepCode</body></html>" > new_ui/frontend/dist/index.html && touch mcp_agent.config.yaml mcp_agent.secrets.yaml && DEEPCODE_ENV=docker python3 new_ui/backend/main.py` [ref_id=1]. Step 2 — Exploit: `curl "http://127.0.0.1:8000/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fprivate%2Fetc%2Fpasswd"` reads `/etc/passwd`; `curl "http://127.0.0.1:8000/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2FUsers%2F$(whoami)%2F.ssh%2Fid_rsa"` reads SSH private keys [ref_id=1].

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.