CVE-2026-87008: CVE-2026-87008: Out-of-Root Arbitrary File Read and Overwrite via Symlink Following in code-graph-rag
CVE-2026-87008: Out-of-Root Arbitrary File Read and Overwrite via Symlink Following in code-graph-rag Vulnerability ID: CVE-2026-87008 CVSS Score: 7.1 Published: 2026-11-09 CVE-2026-87008 (GHSA-85gg-2gfq-q95m) is a
CVE-2026-87008: Out-of-Root Arbitrary File Read and Overwrite via Symlink Following in code-graph-rag
Vulnerability ID: CVE-2026-87008
CVSS Score: 7.1
Published: 2026-11-09
CVE-2026-87008 (GHSA-85gg-2gfq-q95m) is a high-severity symbolic link following and path traversal vulnerability in the code-graph-rag Python package prior to version 0.0.589. The flaw resides in the should_skip_path path validation routine inside codebase_rag/utils/path_utils.py, which performs directory containment checks using unresolved lexical paths rather than canonicalized filesystem paths. Consequently, symbolic links committed to an untrusted repository that point to targets outside the project root bypass boundary enforcement. Attackers who supply a crafted repository containing symbolic links can leverage the AstGrepService tool (structural_search and structural_replace) to read or overwrite arbitrary files on the host filesystem within the privileges of the running process.
TL;DR
Versions of code-graph-rag prior to 0.0.589 fail to resolve symbolic links before validating repository path containment in should_skip_path. By placing a symbolic link pointing to an external file within an analyzed repository, an attacker can read or overwrite arbitrary files on the host via structural_search and structural_replace, bypassing security boundary checks and Model Context Protocol (MCP) approval gates.
β οΈ Exploit Status: POC
Technical Details
- CVE / GHSA ID: CVE-2026-87008 / GHSA-85gg-2gfq-q95m
- Vulnerability Class: CWE-59 (Link Following) / CWE-22 (Path Traversal)
- CVSS v3.1 Score: 7.1 High (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N)
- Affected Component: should_skip_path() in codebase_rag/utils/path_utils.py & AstGrepService
- Affected Versions: code-graph-rag < 0.0.589
- Patched Version: code-graph-rag 0.0.589
- Impact: Arbitrary out-of-root file read and file overwrite
- Exploit / KEV Status: Public PoC Available / Not in CISA KEV (EPSS: 0.26%)
Affected Systems
- vitali87/code-graph-rag (PyPI package: code-graph-rag)
-
code-graph-rag: < 0.0.589 (Fixed in:
0.0.589)
Code Analysis
Commit: 2648c95
fix: reject symlinks resolving outside the project root in should_skip_path
--- a/codebase_rag/utils/path_utils.py
+++ b/codebase_rag/utils/path_utils.py
@@ -120,6 +120,14 @@ def should_skip_path(
_is_file = path.is_file() if is_file is None else is_file
if _is_file and path.suffix in cs.IGNORE_SUFFIXES:
return True
+ # Containment below is lexical, so a symlink whose target escapes the root
+ # would pass it and let a repo-scoped sweep read or overwrite outside files
+ # (GHSA-85gg-2gfq-q95m). Resolve first, mirroring validate_project_path
+ # (decorators.py) and absolute_path_within_project_root (this module).
+ try:
+ path.resolve().relative_to(repo_path.resolve())
+ except ValueError:
+ return True
rel_path = cached_relative_path(path, repo_path)
rel_path_str = rel_path.as_posix()
# a trailing slash marks the path as a directory for dir-only patterns.
Exploit Details
- GitHub: Public Proof-of-Concept repository demonstrating symlink escape via AstGrepService in code-graph-rag (GHSA-85gg-2gfq-q95m / CVE-2026-87008).
Mitigation Strategies
- Upgrade
code-graph-ragto version 0.0.589 or later to enforce canonical path resolution inshould_skip_path. - Configure Git with
core.symlinks=falsewhen cloning untrusted repositories for static analysis or RAG indexing. - Execute
code-graph-ragand associated MCP tool servers inside isolated containers without access to sensitive host directories. - Pre-scan untrusted repositories for symbolic links (
find . -type l) and reject or sanitize them prior to indexing.
Remediation Steps:
- Identify all environments, developer workstations, and CI/CD pipelines running
code-graph-ragversions prior to0.0.589. - Update the package via pip (
pip install --upgrade "code-graph-rag>=0.0.589") or uv (uv add "code-graph-rag>=0.0.589"). - Verify the installed version using
pip show code-graph-ragto confirm version0.0.589or newer is active. - If running as an MCP server, restart the MCP host application or agent runner to ensure the updated Python module is loaded into memory.
References
- GitHub Security Advisory GHSA-85gg-2gfq-q95m
- Fix Commit: reject symlinks resolving outside the project root in should_skip_path
- code-graph-rag Release v0.0.589
- NVD - CVE-2026-87008
- CVE.org Record: CVE-2026-87008
- CVEListV5 JSON Record for CVE-2026-87008
- GitHub - squeeze440/code-graph-rag-PoC
Read the full report for CVE-2026-87008 on our website for more details including interactive diagrams and full exploit analysis.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.