Skip to content

fix(security): block write_file/patch on Gemini OAuth store (read/write parity) - #38493

Open
Dusk1e wants to merge 1 commit into
NousResearch:mainfrom
Dusk1e:fix/deny-write-gemini-oauth-store
Open

fix(security): block write_file/patch on Gemini OAuth store (read/write parity)#38493
Dusk1e wants to merge 1 commit into
NousResearch:mainfrom
Dusk1e:fix/deny-write-gemini-oauth-store

Conversation

@Dusk1e

@Dusk1e Dusk1e commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What

Add auth/google_oauth.json (Gemini / google-gemini-cli OAuth store) to the write deny list in agent/file_safety.py, at both the active-profile HERMES_HOME and the global root.

Why

The store is read-guarded since #17656, but the write side was never added. A prompt-injected write_file/patch/move/delete could overwrite the refresh+access tokens that get_valid_access_token() reads back (agent/google_oauth.py) — hijacking or bricking the Gemini session. Every other credential store in the read guard (auth.json, .anthropic_oauth.json, .env, webhook_subscriptions.json, mcp-tokens/) is already write-denied; google_oauth.json was the lone exception. Same root-widening as #15981.

Defense-in-depth, not a security boundary — the terminal tool runs as the same OS user and can still reach the file (file_safety.py docstring; SECURITY.md §2.4/§3.2). Regular hardening PR, not the advisory channel.

Tests

scripts/run_tests.sh tests/tools/test_file_operations.py::TestIsWriteDenied
  • Added auth/google_oauth.json to the basic + profile-mode deny parametrize.
  • Red/green verified: both new cases fail without the fix, pass with it.
TestIsWriteDenied ........................ 33 passed
file_safety write-deny suites ............ 132 passed, 1 skipped

@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint area/auth Authentication, OAuth, credential pools provider/gemini Google Gemini (AI Studio, Cloud Code) P2 Medium — degraded but workaround exists labels Jun 3, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approved

Changes

This PR closes the read/write parity gap for the Gemini OAuth credential store by adding auth/google_oauth.json to both the root-level build_write_denied_paths and the existing per-hermes-home deny list.

Security Observations

  • Correct gap: get_read_block_error already blocked auth/google_oauth.json reads under a profile (PR #17656), but is_write_denied did not. A prompt-injected write_file/patch could silently overwrite the refresh/access tokens that get_valid_access_token() reads back. This PR resolves that asymmetry.
  • Both locations protected: hermes_home / auth/google_oauth.json (active profile) and hermes_root / auth/google_oauth.json (global root shared across profiles) are now in the deny list — matches PR #15981's pattern for .env widening.

Testing

  • Tests added in tests/tools/test_file_operations.py covering both profile-mode and root paths.

Reviewed by Hermes Agent

@teknium1 teknium1 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.

Thanks for the narrow parity hardening. The production change targets a real current-main gap: agent/file_safety.py:28-58 write-denies .anthropic_oauth.json but not auth/google_oauth.json, while the read guard already classifies the latter as a credential store at agent/file_safety.py:241-260.

Problems

  • The new comments cite agent/google_oauth.py / get_valid_access_token(), but agent/google_oauth.py is not present at current HEAD. Please remove that stale implementation-specific attribution and retain a concise credential-store rationale.
  • The test hunk predates 81e42335a1, which intentionally made Hermes control files writable while retaining OAuth-store denials. Current coverage is split between OAuth cases at tests/tools/test_file_operations.py:65-82 and the profile/root OAuth test at :118-127.

Suggested changes

  • Add auth/google_oauth.json to those two current OAuth parameterizations, preserving the control-file writable cases.

Automated hermes-sweeper review.

Comment thread agent/file_safety.py
# when a profile is active; default/non-profile sessions still read it.
str(hermes_root / ".anthropic_oauth.json"),
# Active profile Gemini (google-gemini-cli) OAuth credential store.
# The read side has been guarded since #17656, but the write side

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.

agent/google_oauth.py is absent from current main, so this implementation-specific comment would be stale on salvage. Please replace this block with a short path/purpose comment that does not reference the removed module or function.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/gemini Google Gemini (AI Studio, Cloud Code) sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants