Two file-escape flaws found in Code Graph RAG agent tools
Advisories published on 9 November 2026 describe a path traversal in the read_file tool and symlink following in structural search and replace.
By The Agentic Times ·

Two security advisories published on 9 November 2026 describe separate flaws in Code Graph RAG, a Python package that indexes source code and exposes it to AI coding agents through the Model Context Protocol (MCP), a standard way for AI models to call external tools. Both flaws let an attacker reach files outside the configured project root. One allows arbitrary file reads; the other allows reads and writes.
The first advisory, GHSA-vvr2-h2jp-838m, tracked as CVE-2026-77604, concerns the read_file MCP tool in codebase_rag/mcp/tools.py. According to the advisory, the tool takes a different code path when a caller supplies an offset or limit value. That paginated branch builds the target path by joining the project root with the user-supplied file path, then opens it without checking the result stays inside the root. Python's pathlib discards the left-hand part of such a join when the right-hand side is an absolute path, so a request for /etc/passwd resolves to exactly that file.
The advisory notes that the non-paginated branch is protected by a validate_project_path decorator that resolves the path and checks containment, but that this decorator is never applied in the paginated branch. The default host for the HTTP MCP transport is 0.0.0.0, and the advisory states the attack is unauthenticated and network-accessible when HTTP transport is configured. The same code path is also reachable over the stdio transport. A proof of concept using Docker reads /etc/hosts from outside a test project root. The advisory includes a patch that resolves both paths and checks one is relative to the other.
The second advisory, GHSA-85gg-2gfq-q95m, tracked as CVE-2026-87008, covers the structural_search and structural_replace tools, both backed by AstGrepService. According to the advisory, the service walks the project directory and gates each file through a containment check performed lexically on the unresolved path. It never calls Path.is_symlink() or .resolve(). As a result, a symbolic link placed inside a repository that Code Graph RAG analyses is treated as an in-scope file, and reads follow it to its real target. With structural_replace and dry_run=False, the tool overwrites the real target file.
The advisory says this was tested at commit 90a3ed3, pyproject version 0.0.550, which was main at the time of testing. It states that commit already contains the fix for the earlier read_file issue and a newer bearer-token gate on HTTP MCP exposure, and describes the symlink issue as distinct and still open, with a worse impact because it allows writes.
On reachability, the advisory says structural_search carries no approval flag, so in AI-orchestrator mode the model can call it without human confirmation. structural_replace is marked as requiring approval, but the advisory says that flag is only enforced by the agent loop of pydantic-ai, and that the MCP server registration bypasses it entirely by calling the underlying function directly. Any MCP client able to call tools can therefore invoke structural_replace with dry_run=False in a single request.
The advisory contrasts this with the package's own file read, write and edit tools, which use the resolving decorator, and quotes an internal docstring in the project stating that the resolve calls are load-bearing because containment is checked lexically.
Sources
- github.comhttps://github.com/advisories/GHSA-vvr2-h2jp-838m
- github.comhttps://github.com/advisories/GHSA-85gg-2gfq-q95m
