Overview
A high-severity security vulnerability tracked as CVE-2026-87008 has been disclosed in Code Graph RAG, an AI-powered knowledge graph and retrieval system for querying and editing multi-language codebases. The flaw allows attackers to bypass path containment checks and access files outside the configured project root through symbolic link manipulation.
Vulnerability Details
The vulnerability exists in the AstGrepService component within `codebase_rag/tools/ast_grep_service.py`. According to the GitHub security advisory GHSA-85gg-2gfq-q95m, the service enumerates files beneath the project root and relies on `should_skip_path` in `codebase_rag/utils/path_utils.py` to classify them. However, the containment check operates on unresolved lexical paths rather than resolved filesystem paths.
A symbolic link planted inside an analyzed repository can reference a file outside the configured root while still appearing to be in scope. The `structural_search` tool follows the link and discloses readable content without an approval gate, while `structural_replace` with `dry_run=False` follows it and overwrites writable content.
Technical Root Cause
The advisory explains that the path-containment check in `should_skip_path` and `_classify_file` is performed lexically on the unresolved path. The code never checks `Path.is_symlink()` or calls `.resolve()`, unlike the project’s own `validate_project_path` decorator used elsewhere in the codebase.
Specifically:
- `_iter_source_files` walks `self.project_root` with `os.walk()` and treats every non-directory entry, including symlinks, as an in-scope file
- `_classify_file` performs containment checks using `should_skip_path()` followed by `abs_path.relative_to(self.project_root)` without resolving the path
- `should_skip_path` computes `rel_path = file_path.relative_to(repo_path)` without calling `.resolve()` or checking for symlinks
The read sink occurs in the `search` method at line 143-144, where `self._read(abs_path)` calls `path.read_text()`, which Python follows through the symlink. The write sink occurs in the `replace` method at line 208, where `abs_path.write_text(new_source, …)` overwrites the real target file when `dry_run=False`.
Affected Versions and Systems
According to the NVD entry and GitHub advisory, the vulnerability affects Code Graph RAG version 0.0.588 and earlier. The issue impacts both the MCP (Model Context Protocol) tools and agentic AI tools backed by AstGrepService.
Exploitation and Impact
The advisory states that a remote or local attacker who can get a symbolic link included in a source-code repository that code-graph-rag analyzes can exploit this vulnerability. The `structural_search` tool carries no `requires_approval` flag, meaning in AI-orchestrator mode the model can call it autonomously with no human confirmation.
While `structural_replace` is marked `requires_approval=True`, this flag is only enforced by pydantic-ai’s agent loop. The MCP server path bypasses it entirely, as `MCPToolsRegistry.structural_replace` calls `self._structural_editor_tool.function(…)` directly with no approval concept.
The advisory notes this is “a distinct, still-open issue” separate from a prior advisory (GHSA-vvr2-h2jp-838m) concerning paginated read_file path traversal, and represents “a strictly worse impact (write, not just read).”
Proof of Concept
The GitHub advisory includes a proof of concept demonstrating the vulnerability. The PoC creates a symbolic link inside a safe project root pointing to a file outside that root, then uses AstGrepService to search for and replace content, successfully reading and modifying the external file.
Patch and Mitigation
Version 0.0.589 patches the vulnerability. The fix, committed as 2648c95aa550ce2d9361a8e75ed669d5f4b451b8, adds symlink resolution to the `should_skip_path` function before performing containment checks.
The patch adds the following logic to `codebase_rag/utils/path_utils.py`:
“`python
try:
path.resolve().relative_to(repo_path.resolve())
except ValueError:
return True
“`
This mirrors the approach used in `validate_project_path` and `absolute_path_within_project_root` elsewhere in the codebase. The fix includes 89 lines of new test coverage in `codebase_rag/tests/test_symlink_containment.py` to verify that symlinks resolving outside the root are rejected while those inside are kept.
The release notes for v0.0.589, published on August 10, 2026, state: “Upgrade is strongly recommended for anyone running cgr (CLI, agent, or MCP) against untrusted repositories.”
CVSS Score
The vulnerability has been assigned a CVSS score of 7.1, classified as HIGH severity according to the NVD entry.
Recommendations
Users of Code Graph RAG should immediately upgrade to version 0.0.589 or later, particularly if analyzing repositories from untrusted sources. Organizations running the CLI, agent, or MCP server against repositories they do not fully control face the highest risk and should prioritize this update.



