# Risk map — google-gemini/gemini-cli

> Canonical page: https://codevetter.com/unpack/gemini-cli/risk-map

# Risk map — google-gemini/gemini-cli

Scanned commit d5b3e3accb26000d273abf16e0f1dd83aa5428a9 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The riskiest surfaces are the ones that execute or fetch code: ShellTool + ShellExecutionService (model-generated commands on the host, mitigated by policy/confirmation/sandbox), the sandbox relaunch path itself (exec/spawn of docker, podman, sandbox-exec), extension installation (git clone / GitHub release downloads, consent-gated), the toolDiscoveryCommand (arbitrary configured command whose stdout is parsed into tools), custom-command shell injection (!{...} processors), and the a2a-server which ships hardcoded demo credentials. Config.ts is a 4200-line god object and the two-process relaunch + ConsolePatcher/stdio interception are fragile coupling hotspots. Credential storage (OAuth via keychain/file fallback, apiKeyCredentialStorage, MCP oauth-token-storage) is sensitive file IO outside the repo.
- a2a-server customUserBuilder authenticates with literal hardcoded values — Bearer 'valid-token' and Basic 'admin:password' — which would accept those credentials on any deployed instance of this Express app. — [packages/a2a-server/src/http/app.ts#L96-120](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/a2a-server/src/http/app.ts#L96-L120)
- ShellTool executes model-generated shell commands; mitigations are layered (shell-utils root-command parsing for policy matching, PolicyDecision gating, user confirmation details of type 'exec', optional sandboxing via sandboxManager, untrusted-context tracking for build/test commands) but the blast radius is the user's shell. — [packages/core/src/tools/shell.ts#L37-66](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/tools/shell.ts#L37-L66) [packages/core/src/services/shellExecutionService.ts#L441-475](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/services/shellExecutionService.ts#L441-L475) [packages/core/src/utils/untrustedContextTracker.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/utils/untrustedContextTracker.ts) [packages/core/src/scheduler/policy.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/scheduler/policy.ts)
- The sandbox path spawns external binaries (docker/podman/sandbox-exec) and rewrites argv/stdin; sandbox.ts uses exec/execSync/spawnSync heavily and manages temp seatbelt profile files — a failure here can strand processes or silently run unsandboxed if config detection misfires. (inferred) — [packages/cli/src/utils/sandbox.ts#L7-20](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/utils/sandbox.ts#L7-L20) [packages/cli/src/utils/sandbox.ts#L55-120](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/utils/sandbox.ts#L55-L120) [packages/cli/src/utils/sandboxUtils.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/utils/sandboxUtils.ts) [packages/cli/src/gemini.tsx#L684-737](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L684-L737)
- ToolRegistry.discoverAndRegisterToolsFromCommand spawns a user-configured toolDiscoveryCommand via spawn and JSON.parses its stdout into FunctionDeclarations; DiscoveredTool invocations then spawn toolCallCommand piping params as JSON on stdin — arbitrary local command execution is a designed-in extension surface. — [packages/core/src/tools/tool-registry.ts#L376-539](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/tools/tool-registry.ts#L376-L539) [packages/core/src/tools/tool-registry.ts#L77-120](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/tools/tool-registry.ts#L77-L120)
- Custom TOML commands support !{...} shell injection executed through ShellProcessor, which throws ConfirmationRequiredError to force user approval — a prompt-file → shell-exec path that depends on the confirmation gate not being bypassed. — [packages/cli/src/services/prompt-processors/shellProcessor.ts#L24-53](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/services/prompt-processors/shellProcessor.ts#L24-L53) [packages/cli/src/services/FileCommandLoader.ts#L25-35](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/services/FileCommandLoader.ts#L25-L35)
- Extension installs fetch remote code (cloneFromGit/downloadFromGitHubRelease) and extensions can contribute MCP servers, hooks, policies, and commands — supply-chain risk is gated by maybeRequestConsentOrFail, admin allowlists (applyAdminAllowlist), ExtensionIntegrityManager, and folder trust. — [packages/cli/src/config/extension-manager.ts#L21-24](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/config/extension-manager.ts#L21-L24) [packages/cli/src/config/extension-manager.ts#L44-64](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/config/extension-manager.ts#L44-L64) [packages/cli/src/config/extensions/consent.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/config/extensions/consent.ts) [packages/core/src/config/extensions/integrity.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/config/extensions/integrity.ts)
- Config (packages/core/src/config/config.ts, 4205 lines) concentrates ~200 getters plus lifecycle (auth refresh, tool registry, MCP startup, hooks, extensions) — edits here have the largest blast radius and the file already carries patches like minified-class-name normalization in maybeRegister. — [packages/core/src/config/config.ts#L753](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/config/config.ts#L753) [packages/core/src/config/config.ts#L3939-3964](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/config/config.ts#L3939-L3964)
- The uncaught-exception handler deliberately swallows specific node-pty errors ('Cannot resize a pty that has already exited', EBADF from node-pty stacks) — pragmatic, but any genuinely new fatal error signature matching those strings will also be suppressed. — [packages/cli/src/gemini.tsx#L225-248](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L225-L248)
- Secrets handling spans multiple stores: OAuth creds via oauth2.ts, GEMINI_API_KEY persisted in apiKeyCredentialStorage (keytar on supported platforms, with a documented Linux Secret-Service hang avoided by early return for OAuth/ADC), MCP tokens via keychain/hybrid/file storage — file-permission and keychain-availability edge cases are the sensitive surface. — [packages/core/src/core/apiKeyCredentialStorage.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/core/apiKeyCredentialStorage.ts) [packages/core/src/code_assist/oauth2.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/code_assist/oauth2.ts) [packages/core/src/mcp/token-storage/keychain-token-storage.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/mcp/token-storage/keychain-token-storage.ts) [packages/core/src/mcp/token-storage/hybrid-token-storage.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/mcp/token-storage/hybrid-token-storage.ts) [packages/core/src/core/contentGenerator.ts#L164-172](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/core/contentGenerator.ts#L164-L172)
- stdio is globally intercepted (patchStdio + ConsolePatcher redirecting console.* into coreEvents) and stdin is toggled into raw mode at multiple layers; ordering bugs here caused real issues — the code comments cite silent keystroke loss when stdin listeners drop to zero. — [packages/cli/src/gemini.tsx#L477-481](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L477-L481) [packages/cli/src/gemini.tsx#L828-838](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L828-L838) [packages/cli/src/gemini.tsx#L903-911](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L903-L911) [packages/cli/src/ui/utils/ConsolePatcher.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/ui/utils/ConsolePatcher.ts)
- MCP servers are spawned/connected from settings and extension manifests with OAuth flows (mcp-oauth-provider) and token storage; allowedMcpServerNames and admin policies constrain them, but a malicious or compromised MCP server can inject tool descriptions, prompts (McpPromptLoader), and resources into the model context — flagged by the prompt_injection_mcp eval. (inferred) — [packages/core/src/tools/mcp-client-manager.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/tools/mcp-client-manager.ts) [packages/core/src/mcp/mcp-oauth-provider.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/core/src/mcp/mcp-oauth-provider.ts) [packages/cli/src/services/McpPromptLoader.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/services/McpPromptLoader.ts) [evals/prompt_injection_mcp.eval.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/evals/prompt_injection_mcp.eval.ts)
- --raw-output disables ANSI sanitization of model output in TEXT mode; the code itself warns this 'may contain harmful ANSI sequences (e.g. for phishing or command injection)' and requires --accept-raw-output-risk to suppress the warning. — [packages/cli/src/nonInteractiveCli.ts#L210-218](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/nonInteractiveCli.ts#L210-L218) [packages/cli/src/nonInteractiveCli.ts#L340-343](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/nonInteractiveCli.ts#L340-L343)
- Workspace-trust is a security boundary: trustedFolders.json gates folder trust, untrusted folders restrict which extensions/commands/hooks load (FileCommandLoader checks isTrustedFolder; LiteRt binaryPath/autoStartServer are deliberately user-scope-only to prevent workspace configs executing arbitrary binaries). — [packages/cli/src/config/trustedFolders.ts](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/config/trustedFolders.ts) [packages/cli/src/services/FileCommandLoader.ts#L75-81](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/services/FileCommandLoader.ts#L75-L81) [packages/cli/src/gemini.tsx#L852-861](https://github.com/google-gemini/gemini-cli/blob/d5b3e3accb26000d273abf16e0f1dd83aa5428a9/packages/cli/src/gemini.tsx#L852-L861)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
