CVE Patch Review

CVE-2026-0755 Root-Cause Patch Review for gemini-mcp-tool 1.1.6

CVE-2026-0755 · Updated 2026-06-19 Root-cause

Summary

The 1.1.6 patch addresses both exploit paths described for CVE-2026-0755: Windows command injection caused by incomplete cmd.exe argument quoting, and arbitrary local file exfiltration caused by unrestricted @file prompt references. The changes remove ineffective manual prompt quoting, add root-bounded validation for @file references, and quote every Windows shell argument rather than only whitespace-bearing tokens. Residual risk remains around the exact @file token grammar and non-RCE environment-variable expansion semantics on Windows, but the patch materially fixes the documented root causes.

Analysis

Vulnerability

CVE-2026-0755 affects gemini-mcp-tool <= 1.1.5 and combines two distinct trust-boundary failures: Windows command injection and cross-platform arbitrary file exfiltration. The NVD and CVE records describe unauthenticated remote code execution on Windows and sensitive file disclosure through manipulated prompt input in the Gemini CLI integration.

The patch metadata in the upstream commit shows the vulnerable behavior came from two implementation choices. First, geminiExecutor.ts manually wrapped prompts containing @ in double quotes before passing them to spawn. Because the process path uses shell: false outside the Windows shelling path, those quotes were not protective syntax; they were literal bytes in argv, which both corrupted prompt semantics and failed to provide security isolation. Second, commandExecutor.ts only quoted Windows arguments when they contained whitespace or a double quote, leaving spaceless metacharacter-bearing tokens such as a&calc able to break command boundaries when routed through cmd.exe with shell: true.

The exfiltration issue is also straightforward from the patch notes: the Gemini CLI interprets @path tokens by inlining file contents. If prompt text is attacker-influenced and references are unrestricted, inputs like @/etc/passwd, @~/.ssh/id_rsa, or @../../secret can read arbitrary local files. That is a classic capability leak from prompt text into filesystem reads.

// Vulnerable prompt handling in geminiExecutor.ts
const finalPrompt = prompt_processed.includes('@') && !prompt_processed.startsWith('"') 
  ? `"${prompt_processed}"` 
  : prompt_processed;
args.push(CLI.FLAGS.PROMPT, finalPrompt);

// Vulnerable Windows quoting in commandExecutor.ts
const safeArgs = isWindows
  ? args.map(a => {
      const s = String(a);
      return /[\s"]/ .test(s) ? `"${s.replace(/"/g, '""')}"` : s;
    })
  : args;

Sources: official patch commit, NVD entry, CVE record.

Patch

The 1.1.6 patch makes three security-relevant changes in the upstream commit 715d567f7905eaa778d7bd887c5b2332ac0b565a.

First, it removes manual double-quote wrapping from the prompt path in geminiExecutor.ts and passes the prompt verbatim as a single argv element. This aligns the code with the actual process model: when spawn is not using a shell, argument boundaries are already preserved by the API, so adding quotes only mutates the payload.

Second, it introduces assertSafeFileReferences(), which scans prompt text for @token references and rejects references that resolve outside the current working directory. The implementation explicitly blocks absolute-path escape, parent traversal, and ~-prefixed home references by resolving against process.cwd() and enforcing containment within that root.

Third, it hardens the Windows shell path in commandExecutor.ts by quoting every argument passed through cmd.exe, not only arguments containing whitespace. This is the critical fix for metacharacter injection in spaceless tokens. The helper also doubles embedded quotes and trailing backslashes before closing quotes.

function quoteForCmd(arg: string): string {
  const body = String(arg).replace(/(\\*)"/g, '$1$1""').replace(/(\\+)$/, '$1$1');
  return `"${body}"`;
}

export function assertSafeFileReferences(prompt: string, root: string = process.cwd()): void {
  const normalizedRoot = path.resolve(root);
  for (const match of prompt.matchAll(/@(\S+)/g)) {
    const ref = match[1];
    const resolved = path.resolve(normalizedRoot, ref);
    const escapesRoot =
      resolved !== normalizedRoot && !resolved.startsWith(normalizedRoot + path.sep);
    if (ref.startsWith('~') || escapesRoot) {
      throw new Error(`Refusing @file reference outside the project directory: "@${ref}".`);
    }
  }
}

The changelog in the same commit explicitly states that the release is an emergency security patch for CVE-2026-0755 and that the Windows hardening applies to all tools that shell out, including ask-gemini, brainstorm, and ping.

Review

Pros

  • The patch addresses the actual root causes rather than only filtering specific payload examples. On Windows, quoting every argument is the correct response when using shell: true with cmd.exe, because metacharacters are dangerous even without whitespace.
  • Removing manual prompt quoting is technically correct for the documented spawn behavior. It eliminates a false sense of safety and fixes the prompt corruption side effect noted in the changelog.
  • assertSafeFileReferences() preserves intended @file functionality while constraining it to the project root, which is a reasonable least-privilege boundary for a developer tool.
  • The implementation explicitly handles ~ references, which is important because path.resolve() alone would not treat tilde as home expansion.
  • The patch is localized and low-risk operationally: version bump, targeted executor changes, and no broad architectural churn.

Cons

  • The file-reference parser is regex-based with /@(\S+)/g, so its security coverage is only as accurate as the Gemini CLI's real tokenization rules. If the downstream CLI accepts quoted paths, escaped whitespace, or other syntactic forms not matched by this regex, there could be residual bypass surface.
  • The containment model is tied to process.cwd(). That is sensible, but it is a policy choice rather than a capability model; environments with symlinks, bind mounts, or unusual working-directory control may need additional review depending on how the CLI resolves file references.
  • The Windows quoting helper notes that cmd still expands %VAR% and !VAR! inside quotes. The commit correctly characterizes this as environment disclosure rather than command execution, but it remains observable behavior if attacker-controlled prompt text reaches shell arguments.
  • The patch hardens the current shelling strategy instead of eliminating shell: true on Windows. That is pragmatic, but shell removal would be a stronger long-term design if compatibility permits.

Verdict

Root-cause.

This patch materially fixes the documented exploit primitives in a source-grounded way. The Windows RCE path is addressed by changing the quoting model from conditional to universal for cmd.exe-routed arguments, which directly closes metacharacter breakout in spaceless tokens. The arbitrary file exfiltration path is addressed by validating @file references before they reach the Gemini CLI's inlining parser and by removing the ineffective manual quoting that previously corrupted prompt handling. While there are still edge conditions worth regression-testing against the exact downstream CLI grammar, the patch is not merely cosmetic or signature-based; it corrects the trust-boundary mistakes described in the upstream commit and is consistent with the vulnerability scope in the NVD and CVE record.

Sources