fix(security): deny home-root single-file credential stores in media delivery - #51453
fix(security): deny home-root single-file credential stores in media delivery#51453r266-tech wants to merge 1 commit into
Conversation
…delivery build_write_denied_paths (agent/file_safety.py) already forbids the agent from writing ~/.netrc, ~/.pgpass, ~/.npmrc, ~/.pypirc and ~/.git-credentials, but the media-delivery denylist did not cover them. NousResearch#51055 extended that denylist so the delivery side can't trail the write side, but only added the ~/.hermes-root credential files and the home credential directories; these five home-root single-file stores were missed. In default (non-strict) media-delivery mode any file not under a denied path is deliverable, so a prompt-injected or buggy agent could auto-attach a plaintext credential file (Git tokens, FTP/HTTP logins, Postgres passwords, npm/PyPI registry tokens) to a chat reply. Add the five basenames to a new _MEDIA_DELIVERY_DENIED_HOME_FILES tuple and append them (joined to $HOME) in _media_delivery_denied_paths(), matched by exact path. An ordinary file in $HOME still delivers (exact-match, no over-blocking). Adds regression tests for denial and non-over-blocking.
|
Thanks for the focused security fix. The premise remains valid on current The proposed exact-path additions match Automated hermes-sweeper review. |
|
looks mergeable A patch replay onto current Security evidence:
Not checked:
Signed: GPT-5.6-sol-xhigh in Codex |
Problem
build_write_denied_paths(agent/file_safety.py:49-53) already forbids the agent from writing five home-root single-file credential stores:But the media-delivery denylist in
gateway/platforms/base.pydoes not cover them. #51055 recently extended that denylist so "the delivery/exfil side can't trail the write side", mirroring the write guard — but it only added the~/.hermes-root credential files (_ROOT_CREDENTIAL_FILES) and the home credential directories (_MEDIA_DELIVERY_DENIED_HOME_SUBPATHS:.ssh,.aws, …). The five home-root single-file stores above were missed.In the default (non-strict) media-delivery mode,
validate_media_delivery_pathaccepts any existing file that isn't under a denied prefix (base.py). SoMEDIA:~/.git-credentials,MEDIA:~/.netrc, etc. remain auto-deliverable — a prompt-injected or buggy agent can attach a plaintext credential file (Git remote tokens, FTP/HTTP logins, Postgres passwords, npm/PyPI registry tokens) straight into a chat reply. This is the exact read/write-vs-delivery divergence #51055 set out to close, and the same threat model the maintainer accepted for~/.hermes/google_token.jsonthere.Fix
Add the five basenames to a new
_MEDIA_DELIVERY_DENIED_HOME_FILEStuple and append them (joined to$HOME) inside_media_delivery_denied_paths(), right next to the existing home-credential-directory loop. They are matched by exact path in_path_under_denied_prefix(which already handlesresolved == resolved_denied), so:~/.netrc/~/.pgpass/~/.npmrc/~/.pypirc/~/.git-credentialsare denied.$HOME(not one of these basenames) still delivers — the entries are exact-match, so they don't over-block the user's own home tree.Scoped to these five home-root credential files only; the per-directory and
~/.hermes-root denials from #51055 (and the sibling targeted PRs #37222 mcp-tokens, #41071 state.db) are untouched.Tests
tests/gateway/test_platform_base.py:test_denylist_blocks_home_root_credential_files— all five are denied in default mode.test_non_credential_home_file_still_delivers— a normal$HOMEfile still delivers (exact-match, no over-blocking).Mirrors the existing
test_denylist_still_blocks_credentials/test_denylist_blocks_google_token_default_modepattern.