Repository navigation
fix(core): scope untrusted flag checks to external output and remember approved flags - #29833
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request improves the user experience in Gemini CLI by refining how untrusted flags and build file modifications are tracked. By distinguishing between local shell output and external sources (like web or MCP), the agent avoids repetitive confirmation requests for benign flags or workspace paths. Additionally, it introduces session-level persistence for approvals and cleans up UI notifications to reduce clutter. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
|
📊 PR Size: size/L
|
There was a problem hiding this comment.
Code Review
This pull request enhances untrusted context tracking and flag detection by distinguishing between local shell output and external content, ignoring workspace-local paths, and remembering approved flags and build files within a session to prevent redundant confirmation prompts. It also adds support for tracking remote sources and deduplicates modified build file names in UI warnings. The feedback suggests using optional chaining on match[1] in untrustedContextTracker.ts to prevent a potential runtime TypeError if the capture group is undefined.
Note: Security Review did not run due to the size of the PR.
ad67029 to
5c77bf1
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces untrusted flag tracking and session-scoped approvals to prevent redundant confirmation prompts for previously approved commands, along with tracking for modified build files and remote content command detection to preserve external provenance. Feedback on these changes highlights three key robustness and security improvements: wrapping path.resolve in a try-catch block within isWorkspaceLocalPath to handle malformed tokens defensively, using a regular expression instead of a strict string match to parse the source attribute of untrusted contexts, and updating isRemoteContentCommand to prevent bypasses via prefix commands like sudo or env.
Note: Security Review did not run due to the size of the PR.
2d7a0ea to
ea37249
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces enhancements to untrusted context tracking and shell command execution safety. Key updates include deduplicating modified build file names in CLI warnings, scoping untrusted flag detection to the workspace boundary, and implementing session-based acknowledgements for approved flags and build files to prevent redundant confirmation prompts. Additionally, it adds support for identifying remote content retrieval commands (like curl and wget) to preserve external provenance. I have no feedback to provide as there are no review comments.
Note: Security Review did not run due to the size of the PR.
|
✅ 70 tests passed successfully on gemini-3-flash-preview. 🧠 Model Steering GuidanceThis PR modifies files that affect the model's behavior (prompts, tools, or instructions).
This is an automated guidance message triggered by steering logic signatures. |
Head branch was pushed to by a user without write access
dfbfe9e to
cbf78ed
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request enhances security and usability when executing shell commands by tracking untrusted flags and modified build files across sessions, deduplicating build file warnings in the UI, and identifying remote content retrieval commands to preserve their external provenance. The review feedback highlights two key areas for improvement: first, sanitizing the source parameter in wrapUntrusted to prevent potential attribute breakout or prompt injection; second, wrapping the call to getCommandRoots in a try-catch block within ShellToolInvocation to prevent unhandled exceptions from crashing tool invocations on malformed commands.
Note: Security Review did not run due to the size of the PR.
cbf78ed to
9931d52
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request enhances untrusted context tracking and session-scoped approval mechanisms. Key changes include deduping modified build file names in caution warnings, resetting tracked build file edits and approved command flags upon starting a new session, and refining untrusted flag detection by distinguishing local shell output from external content. Additionally, remote content commands (such as curl or wget) now record a source attribute on <untrusted_context> tags to maintain external provenance. Feedback is provided regarding a potential crash in packages/core/src/tools/shell.ts where getCommandRoots(command) is called directly in getConfirmationDetails without error handling; wrapping this call in a try-catch block with a safe fallback is recommended.
Note: Security Review did not run due to the size of the PR.
…r approved flags Output of the agent's own shell commands was indexed like content returned by web and MCP tools, so routine flags and workspace paths that appeared in local output kept requesting confirmation, and approvals were not retained. - Index run_shell_command output separately. Unknown flags are matched only against output of other tools or of remote retrieval commands (curl, wget, gh, ssh), now tagged source="shell_remote". High-risk value flags, URLs, scripts and paths outside the workspace are still matched against all output. - Treat path arguments inside the workspace (WorkspaceContext) as local, except executable scripts and values of high-risk value flags. - Remember flags approved for the same root commands and clear the modified build file state after a build command is approved. - Reset both states when the session changes (/clear, session resume). - List each modified build file name once in the confirmation warning. Related to google-gemini#29680 Related to google-gemini#29687 Related to google-gemini#29682
9931d52 to
2453343
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request enhances untrusted context tracking and security confirmation mechanisms for shell commands. Key changes include deduplicating modified build file names in UI warnings, tracking and acknowledging approved untrusted flags within a session to prevent redundant prompts, scoping untrusted flag detection to the workspace (ignoring workspace-local paths), and distinguishing between local shell output and remote content sources (e.g., curl, wget). Comprehensive unit tests have been added across the CLI and core packages to validate these behaviors. There are no review comments to evaluate, so I have no feedback to provide.
Note: Security Review did not run due to the size of the PR.
Pulls in upstream through v0.67.0-nightly.20261022 (rep-main == upstream/main). Conflicts (3 files) resolved toward upstream, because PR google-gemini#29833 replaced the approach the fork had taken: - untrustedContextTracker.ts: the fork skipped indexing *all* shell-tool output ("shell auto run"), upstream instead keeps it in untrustedTokens while recording provenance in externalTokens, and matches only non-high-risk flags against external content. Keeping the fork's skip would have silently disabled upstream's high-risk flag checks (e.g. --test_arg) and its acknowledgement logic, so the skip block was dropped along with its now-unused SHELL_TOOL_NAMES import. The fork's original goal (no re-prompting on a flag the agent ran itself) is still met, by acknowledgement. - untrustedContextTracker.test.ts: taken from upstream; its provenance tests encode the design above. - ToolConfirmationMessage.test.tsx: both sides added an unrelated test at the same spot; kept both. Known host-only test gap: packages/core/src/config/config.test.ts cannot load on android-arm64 (@lydell/node-pty has no android-arm64 binary). Pre-existing.
Summary
This PR reduces repeated confirmation requests for shell commands in Gemini CLI.
Flags and paths that only appear in the output of the agent's own shell commands
no longer count as external input, path arguments inside the workspace aren't
reported, and an approval now covers the same flags and root commands for the
rest of the session. It also clears the modified build file notice after you
approve a build command, resets both states when the session changes, and lists
each build file name once.
These changes address the frequent prompts in YOLO mode that users still report
after #29672, for example after
pwd,git diff, a test runner's usage text,or an
npmhint. Flags that come fromweb_fetch,web_search, MCP, or remoteretrieval output still request confirmation.
Details
Gemini CLI wraps
run_shell_commandoutput in<untrusted_context>tags, thesame way it wraps
web_fetchand MCP output.extractUntrustedContext()indexed all of that content as one set, so
findUntrustedFlags()reported flagsand paths that only appeared in the output of the agent's own commands. When
these checks match, the scheduler asks for confirmation (interactive) or denies
the call (non-interactive), even in YOLO mode. Approvals weren't retained, and
the modified build file state was never cleared, not even by
/clear.This PR makes the following changes:
packages/core/src/utils/untrustedContextTracker.ts:extractUntrustedContext()returns a new optionalexternalTokensset thatexcludes
run_shell_commandoutput, unless the block carriessource="shell_remote". Check 1A matches flags that aren't inHIGH_RISK_VALUE_FLAGSonly againstexternalTokens.findUntrustedFlags()accepts optional{ cwd, isPathWithinWorkspace }.Path arguments that resolve inside the workspace aren't reported, except
executable scripts, URLs, paths with shell expansions, and values of
HIGH_RISK_VALUE_FLAGS.isRemoteContentCommand()and the session helpersacknowledgeUntrustedFlags(),getUnacknowledgedUntrustedFlags(), andresetAcknowledgedUntrustedFlags().packages/core/src/tools/shell.ts: Uses one helper,getUntrustedFlags(), in bothhasTaintedOrBuildFileRisk()andgetConfirmationDetails(). The helper passes the workspace scope throughWorkspaceContext.isPathWithinWorkspace()and filters flags that were alreadyapproved for the same root commands.
onConfirmrecords the approved flagsand clears the modified build file state, except for cancelled or modified
confirmations. Output of
curl,wget,gh, andsshis tagged withsource="shell_remote".packages/core/src/utils/textUtils.ts:wrapUntrusted()accepts anoptional
sourceattribute. The output doesn't change when no source ispassed.
packages/core/src/config/config.ts:setSessionId()clears both sessionstates, so
/clearand session resume start clean.packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx:Lists each modified build file name once in the build file notice.
untrustedContextTracker.test.ts,shell.test.ts,textUtils.test.ts,config.test.ts, andToolConfirmationMessage.test.tsx.The following behavior doesn't change:
HIGH_RISK_VALUE_FLAGS, URLs, executable scripts, and paths outside theworkspace are still matched against all wrapped output, including shell
output.
web_fetch,web_search, MCP tools, and remote retrievalcommands keeps the existing unknown-flag matching.
the same.
source="shell_remote"attribute on remote retrieval output.Keep these points in mind when you review:
commands with the same root commands and the same flags for the rest of the
session. A new flag or a new build file edit requests confirmation again.
and existing callers keep their current results.
docs/doesn't describe theuntrusted flags confirmation or the build file notice.
removes duplicate build file names.
trusthandling, or change the non-interactive behavior after a build fileedit. Gemini CLI v0.63.0 - breaks yolo mode #29682 asks for a configuration option, so it stays open.
Related Issues
Related to #29680
Related to #29687
Related to #29682
How to Validate
Follow these steps to validate the changes locally:
Run the targeted unit tests in
@google/gemini-cli-core:npm test -w @google/gemini-cli-core -- \ src/utils/untrustedContextTracker.test.ts \ src/tools/shell.test.ts \ src/utils/textUtils.test.ts \ src/config/config.test.ts \ src/scheduler/scheduler.test.tsRun the confirmation UI tests in
@google/gemini-cli:npm test -w @google/gemini-cli -- \ src/ui/components/messages/ToolConfirmationMessage.test.tsxVerify that all suites pass (478 core tests with 1 existing skip, and 43 UI
tests). The new tests cover these scenarios:
run_shell_commandoutput, such as annpmhintfor
--legacy-peer-deps, apytest -kusage line, or the lines of agit diff, aren't reported.source="shell_remote"output are stillreported, and so is
python3 -cafter shell output lists-c.pwd,find ., or a stack trace aren'treported, while scripts, URLs, and paths outside the workspace still are.
confirmation again. A cancelled confirmation records nothing, and other
root commands still request confirmation.
after the next build file edit.
resetNewSessionState(), which/clearcalls, clears both states.Run the linter and the TypeScript type checker across all workspaces:
Optional: Check the behavior interactively. Start Gemini CLI with
gemini --approval-mode=yoloin a trusted workspace, and then complete thesesteps:
pwd, and then to list a file inside the printeddirectory with
ls -la. Both commands run without a confirmation.package.jsonand then runnpm test. A singleconfirmation lists
package.jsononce. Select Allow once.npm run lint. The command runs without aconfirmation.
package.jsonagain, and then run/clear. Thenext build command runs without the build file notice.
On Linux (Node.js 26.1.0),
npm run lint,npm run typecheck,npm run test:cifor all workspaces (16,288 tests passed),npm run test:scripts, andnpm run bundlepass locally.Pre-Merge Checklist