Skip to content

fix(core): scope untrusted flag checks to external output and remember approved flags - #29833

Merged
DavidAPierce merged 1 commit into
google-gemini:mainfrom
luisfelipe-alt:bugfix/WT-engineer_570973864
Oct 21, 2026
Merged

DavidAPierce merged 1 commit into
google-gemini:mainfrom
luisfelipe-alt:bugfix/WT-engineer_570973864

Conversation

@luisfelipe-alt

Copy link
Copy Markdown
Contributor

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 npm hint. Flags that come from web_fetch, web_search, MCP, or remote
retrieval output still request confirmation.

Details

Gemini CLI wraps run_shell_command output in <untrusted_context> tags, the
same way it wraps web_fetch and MCP output. extractUntrustedContext()
indexed all of that content as one set, so findUntrustedFlags() reported flags
and 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 optional externalTokens set that
      excludes run_shell_command output, unless the block carries
      source="shell_remote". Check 1A matches flags that aren't in
      HIGH_RISK_VALUE_FLAGS only against externalTokens.
    • 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.
    • Adds isRemoteContentCommand() and the session helpers
      acknowledgeUntrustedFlags(), getUnacknowledgedUntrustedFlags(), and
      resetAcknowledgedUntrustedFlags().
  • packages/core/src/tools/shell.ts: Uses one helper,
    getUntrustedFlags(), in both hasTaintedOrBuildFileRisk() and
    getConfirmationDetails(). The helper passes the workspace scope through
    WorkspaceContext.isPathWithinWorkspace() and filters flags that were already
    approved for the same root commands. onConfirm records the approved flags
    and clears the modified build file state, except for cancelled or modified
    confirmations. Output of curl, wget, gh, and ssh is tagged with
    source="shell_remote".
  • packages/core/src/utils/textUtils.ts: wrapUntrusted() accepts an
    optional source attribute. The output doesn't change when no source is
    passed.
  • packages/core/src/config/config.ts: setSessionId() clears both session
    states, so /clear and session resume start clean.
  • packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx:
    Lists each modified build file name once in the build file notice.
  • Tests: Adds 20 tests across untrustedContextTracker.test.ts,
    shell.test.ts, textUtils.test.ts, config.test.ts, and
    ToolConfirmationMessage.test.tsx.

The following behavior doesn't change:

  • HIGH_RISK_VALUE_FLAGS, URLs, executable scripts, and paths outside the
    workspace are still matched against all wrapped output, including shell
    output.
  • Output from web_fetch, web_search, MCP tools, and remote retrieval
    commands keeps the existing unknown-flag matching.
  • The scheduler handling from fix(core): align policy redirection gates, path validation, and workflow parsing #29506 and the confirmation options in the UI stay
    the same.
  • The text the model receives stays the same, except for the
    source="shell_remote" attribute on remote retrieval output.

Keep these points in mind when you review:

  • Approving a flagged command with Allow once now also applies to later
    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.
  • There are no breaking API changes. The new parameter and fields are optional,
    and existing callers keep their current results.
  • No documentation update is needed, because docs/ doesn't describe the
    untrusted flags confirmation or the build file notice.
  • This PR overlaps with fix(security): reset modified build files upon confirmation and deduplicate filenames (#29687) #29719, which also clears the build file state and
    removes duplicate build file names.
  • This PR doesn't add a settings option to tune the check, change MCP server
    trust handling, or change the non-interactive behavior after a build file
    edit. 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:

  1. 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.ts
  2. Run the confirmation UI tests in @google/gemini-cli:

    npm test -w @google/gemini-cli -- \
      src/ui/components/messages/ToolConfirmationMessage.test.tsx
  3. Verify that all suites pass (478 core tests with 1 existing skip, and 43 UI
    tests). The new tests cover these scenarios:

    • Flags that only appear in run_shell_command output, such as an npm hint
      for --legacy-peer-deps, a pytest -k usage line, or the lines of a
      git diff, aren't reported.
    • Flags from MCP output and from source="shell_remote" output are still
      reported, and so is python3 -c after shell output lists -c.
    • Workspace paths printed by pwd, find ., or a stack trace aren't
      reported, while scripts, URLs, and paths outside the workspace still are.
    • After an approval, the same flags for the same root commands don't request
      confirmation again. A cancelled confirmation records nothing, and other
      root commands still request confirmation.
    • After a build command is approved, the build file notice clears. It returns
      after the next build file edit.
    • resetNewSessionState(), which /clear calls, clears both states.
    • The build file notice lists each file name once.
  4. Run the linter and the TypeScript type checker across all workspaces:

    npm run lint
    npm run typecheck
  5. Optional: Check the behavior interactively. Start Gemini CLI with
    gemini --approval-mode=yolo in a trusted workspace, and then complete these
    steps:

    1. Ask the agent to run pwd, and then to list a file inside the printed
      directory with ls -la. Both commands run without a confirmation.
    2. Ask the agent to edit package.json and then run npm test. A single
      confirmation lists package.json once. Select Allow once.
    3. Ask the agent to run npm run lint. The command runs without a
      confirmation.
    4. Ask the agent to edit package.json again, and then run /clear. The
      next build command runs without the build file notice.

On Linux (Node.js 26.1.0), npm run lint, npm run typecheck,
npm run test:ci for all workspaces (16,288 tests passed),
npm run test:scripts, and npm run bundle pass locally.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@luisfelipe-alt
luisfelipe-alt requested review from a team as code owners October 19, 2026 19:18
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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

  • Reduced redundant shell command prompts: Flags and paths appearing only in local shell command output are no longer treated as external input, significantly reducing unnecessary confirmation prompts.
  • Session-scoped approvals: Once a flagged command is approved, the same flags for the same root commands are automatically permitted for the remainder of the session.
  • Improved build file notification: The build file modification notice now lists each file name only once and is cleared immediately upon approval of a build command.
  • Session state management: Added robust resetting of session-scoped states (approved flags and build file edits) when starting a new session or running /clear.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@github-actions github-actions Bot added the size/l A large sized PR label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

📊 PR Size: size/L

  • Lines changed: 910
  • Additions: +881
  • Deletions: -29
  • Files changed: 10

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread packages/core/src/utils/untrustedContextTracker.ts Outdated
@gemini-cli gemini-cli Bot added the area/security Issues related to security label Oct 19, 2026
@luisfelipe-alt
luisfelipe-alt force-pushed the bugfix/WT-engineer_570973864 branch from ad67029 to 5c77bf1 Compare October 19, 2026 19:44
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread packages/core/src/utils/untrustedContextTracker.ts
Comment thread packages/core/src/utils/untrustedContextTracker.ts Outdated
Comment thread packages/core/src/utils/untrustedContextTracker.ts
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

✅ 70 tests passed successfully on gemini-3-flash-preview.

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • ⚠️ Consider adding Evals: No behavioral evaluations (evals/*.eval.ts) were added or updated in this PR. Consider adding a test case to verify the new behavior and prevent regressions.

This is an automated guidance message triggered by steering logic signatures.

auto-merge was automatically disabled October 20, 2026 19:55

Head branch was pushed to by a user without write access

@luisfelipe-alt
luisfelipe-alt force-pushed the bugfix/WT-engineer_570973864 branch from dfbfe9e to cbf78ed Compare October 20, 2026 19:55
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread packages/core/src/utils/textUtils.ts Outdated
Comment thread packages/core/src/tools/shell.ts Outdated
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread packages/core/src/tools/shell.ts
…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
@luisfelipe-alt
luisfelipe-alt force-pushed the bugfix/WT-engineer_570973864 branch from 9931d52 to 2453343 Compare October 20, 2026 21:14
@luisfelipe-alt

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@DavidAPierce
DavidAPierce added this pull request to the merge queue Oct 21, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 21, 2026
@DavidAPierce
DavidAPierce added this pull request to the merge queue Oct 21, 2026
Merged via the queue into google-gemini:main with commit 120a39d Oct 21, 2026
35 checks passed
leo-je added a commit to leo-je/gemini-cli that referenced this pull request Oct 22, 2026
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.

This branch was successfully deployed

1 active deployment
eval-gate — 24533439 Deployed Oct 20, 2026 by luisfelipe-alt via Evaluate Steering & Regressions #2212
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Issues related to security size/l A large sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants