Aug 1, 2026·6 min read·20 visits
A path traversal vulnerability in gemini-bridge allows attackers to read arbitrary local files by exploiting improper canonicalization and a missing validation check in the server's inline payload preprocessor.
Between versions 1.0.0 and 1.3.1, the gemini-bridge Model Context Protocol (MCP) server failed to restrict candidate file paths to the workspace root when processing files in inline mode. This allowed unauthenticated local users, or remote attackers executing prompt-injection payloads against connected AI agents, to traverse the directory tree and read arbitrary system files. The retrieved contents were subsequently forwarded to the external Gemini AI CLI and returned in the round-trip response.
The gemini-bridge package is an integration framework designed to connect Model Context Protocol (MCP) clients, such as Claude Code, with Google's Gemini AI engine via the official CLI tool. To enrich prompt contexts, the server exposes the consult_gemini_with_files tool, allowing client agents to attach specific workspace files to their outgoing queries. This establishes a high-trust attack surface, as the server must strictly regulate the directory paths it accesses to prevent unauthorized file extraction.
Historically, the server operated under the assumption that path resolution logic would confine the candidate file paths to a specified, secure working directory. However, the path translation workflow in inline mode did not implement adequate checks, enabling arbitrary absolute or relative paths to bypass restriction boundaries. As a result, the tool could be coerced into reading sensitive system configuration files, credentials, or private workspace assets.
Once read, the file contents were seamlessly attached to the outgoing query structure and processed by the LLM CLI. Because the client controls both the target path and the command prompt, an attacker can instruct the model to echo the loaded file verbatim, bypassing typical boundary barriers. This transforms a simple traversal issue into a full disclosure pipeline.
The root cause of this vulnerability lies in two distinct flaws in src/mcp_server.py. The first flaw is the absence of canonicalization within the _resolve_path function. The function did not utilize Python's Path.resolve() method, which meant that symbolic links, Windows 8.3 short names, and relative path traversals (e.g., ../) were not expanded to their absolute real paths prior to validation.
def _resolve_path(directory: str, candidate: str) -> tuple[str, str | None]:
candidate_path = Path(candidate)
abs_path = (
str(candidate_path)
if candidate_path.is_absolute()
else str(Path(directory) / candidate)
)
try:
# Fails to resolve canonical paths before computing relative relation
rel_path = os.path.relpath(abs_path, directory)
except ValueError:
rel_path = None
if rel_path and rel_path.startswith(".."):
rel_path = None
return abs_path, rel_pathThe second, more critical flaw resides in how the _prepare_inline_payload function processed the outputs returned by _resolve_path. When a traversal path or an absolute path escaping the root directory was parsed, _resolve_path correctly detected that the path escaped the root and returned rel_path = None.
However, the calling loop in _prepare_inline_payload did not verify whether rel_path was None. Instead of skipping the file, it executed a fallback option display_name = rel_path or Path(abs_path).name and then directly loaded the file from the unconfined abs_path variable. This allowed any arbitrary file path to pass through the validation check and be read.
The vulnerability was mitigated in version 1.3.1 (Commit 8f3b85afd02b692c4bc974b5176e12fb277ea801). The patch introduces strict canonicalization via Python's Path.resolve() and adds explicit condition checks to the inline payload processing logic.
In the patched implementation, both the workspace root and the target candidate paths are fully resolved to strip out traversals and symbolic link tricks. This canonicalized target is then verified against the canonicalized root directory using abs_path.relative_to(root):
# Annotated Patch Changes in src/mcp_server.py
def _resolve_path(directory: str, candidate: str) -> tuple[str, str | None]:
# Resolve the working directory root and any symbolic links
root = Path(directory).resolve()
candidate_path = Path(candidate)
# Compute and resolve the absolute candidate path
abs_path = (
candidate_path if candidate_path.is_absolute() else root / candidate
).resolve()
try:
# Ensure candidate strictly resides under root using relative_to
rel_path = str(abs_path.relative_to(root))
except ValueError:
# Throws ValueError if candidate is outside root boundaries
rel_path = None
return str(abs_path), rel_pathAdditionally, the patch enforces the path traversal boundary check in the calling loop of _prepare_inline_payload:
for original_path in files:
abs_path, rel_path = _resolve_path(directory, original_path)
# If rel_path is None, the path escaped the root. The file is skipped.
if rel_path is None:
warnings.append(
f"Skipped file outside working directory: {original_path}",
)
continue
display_name = rel_pathThis combined patch ensures that unconfined file paths are discarded before any filesystem reads can occur, effectively mitigating the arbitrary read vector.
An attacker can exploit this vulnerability through local command execution or indirect prompt injection vectors. The primary prerequisite is that the gemini-bridge service must be active and listening for tool calls, which is typical when integrated with an automated agent workflow.
In a direct exploitation scenario, the user or local system components make a direct tool call to the MCP server. By supplying a directory value and an out-of-bounds target file path, they can force the server to load arbitrary files:
{
"method": "tools/call",
"params": {
"name": "consult_gemini_with_files",
"arguments": {
"query": "Please summarize this file verbatim:",
"directory": "/home/user/workspace",
"files": ["../../../../etc/passwd"],
"mode": "inline"
}
}
}In an indirect prompt injection attack, a remote attacker can structure an injection payload (e.g., in a public Git repository description or an issue comment) that trick the client AI agent. When the agent processes the injection, it is instructed to invoke consult_gemini_with_files with malicious parameters, silently exfiltrating targeted system files such as SSH keys or .env credential files.
The confidentiality impact of this vulnerability is high. Because the application runs with the privileges of the local system user running the MCP server, any file readable by that user's shell can be retrieved. This exposes sensitive items such as SSH private keys, environment variables containing API keys, local databases, and configuration settings.
The CVSS v3.1 score is evaluated at 6.2 (Medium), with the vector CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. While classified as a local attack vector (AV:L), the emergence of indirect prompt injection vectors against AI agents allows remote actors to trigger the exploit sequence without possessing direct local console access.
No active exploitation in the wild has been observed, nor has this CVE been listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. However, due to the ease of automated exploitation of prompt-injection targets, instances utilizing unpatched server versions face elevated risk.
The primary remediation for this vulnerability is to upgrade the gemini-bridge package to version 1.3.1 or higher. This release integrates the necessary code-level path validation and canonicalization patches to successfully neutralize directory traversals.
For deployments where immediate updates are not feasible, you can apply temporary mitigations. Restricting write access to the workspace directory prevents attackers from writing symbolic links pointing to sensitive system files. Furthermore, you should deploy the server inside a containerized sandbox or under a restricted user account with minimal filesystem privileges.
Finally, because the tool interface allows specifying the directory argument dynamically, developers should modify client-side integrations to enforce hardcoded, system-defined root paths. This ensures that the agent cannot be tricked into redefining the root workspace to a broader path (like / or C:\) during runtime.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
gemini-bridge eLyiN | >= 1.0.0, < 1.3.1 | 1.3.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Secondary CWE ID | CWE-200 |
| Attack Vector | Local |
| CVSS v3.1 Score | 6.2 |
| Exploit Maturity | Proof-of-Concept (PoC) |
| CISA KEV Status | Not Listed |
| Ransomware Use | No |
The software uses external input to construct a pathname that is intended to identify a file or directory that is located within a restricted directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location outside of the restricted directory.
An incorrect authorization and directory traversal vulnerability in the vm2 library before version 3.11.7 allows remote attackers to bypass the sandbox's external package allowlist. This flaw permits sandboxed code to resolve and execute arbitrary packages available on the host filesystem under host privileges, leading to unauthenticated sandbox escape and host code execution.
A critical vulnerability in the Node.js sandbox library vm2 allows sandboxed code to retrieve the process-wide http.globalAgent and https.globalAgent singletons. By attaching event listeners to these host-realm emitters, sandboxed code can intercept host-realm network requests, capturing sensitive Authorization headers and hijacking active TLSSocket streams.
CVE-2026-92950 (GHSA-jxxv-8r27-vm4p) is a critical sandbox escape vulnerability in the command-line interface of the vm2 library prior to version 3.11.7. The flaw allows untrusted scripts to bypass sandbox constraints and execute arbitrary system commands with the privileges of the host process by exploiting insecure default configurations of the module resolver.
CVE-2026-92948 is a critical sandbox escape vulnerability in the vm2 library affecting versions 3.9.6 through 3.11.6 when executed on Node.js 24 and newer. The vulnerability allows an attacker to bypass built-in module blocking defenses by double-prefixing a restricted module name (such as node:node:test). This permits the loading of the node:test module, whose test runner execution can be leveraged to execute arbitrary shell commands outside the VM sandbox.
A high-severity sandbox escape and state corruption vulnerability exists in the vm2 library (versions 3.11.4 through 3.11.6). The vulnerability is caused by an incomplete blocklist of Node.js-internal registered symbols crossing the sandbox-host bridge boundary. Specifically, the filters in `lib/setup-sandbox.js` and write traps in `lib/bridge.js` omitted the symbols `nodejs.stream.disturbed` and `nodejs.stream.errored`, allowing untrusted code within the sandbox to corrupt host-realm stream state checks.
An architectural evaluation of CVE-2026-73607 in the SiYuan personal knowledge management system. This technical advisory details a Missing Authorization (CWE-862) vulnerability in the Go-based backend kernel, specifically within the outline storage API endpoint. Under certain configurations, authenticated low-privilege users can query metadata, heading structures, and block hierarchies of restricted documents.