Skip to content

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap - #58222

Merged
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/dashboard-credential-guard
Jul 4, 2026
Merged

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap#58222
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:salvage/dashboard-credential-guard

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Salvage of #57833 (@srojk34) onto current main, plus a follow-up that closes the two gaps a basename-only guard left open.

The dashboard managed-files API (/api/files list/read/download) exposed credential stores when the operator points the managed root at HERMES_HOME (the docker run -v ~/.hermes:/opt/data scenario from #57505). The guard only blocked .env/.env.*.

Changes

  • @srojk34's commit (preserved): widen _is_sensitive_filename() past .env to .envrc + the canonical credential basenames (auth.json, .anthropic_oauth.json, google_token.json, webhook_subscriptions.json, bws_cache.json, etc.), case-insensitive.
  • Follow-up (this salvage):
    • Directory-tree gap: mcp-tokens/ (live MCP OAuth tokens) and pairing/ are denied as whole trees by both canonical guards (gateway.platforms.base._ROOT_CREDENTIAL_DIRS, agent.file_safety), but the files API descends into subdirs, so mcp-tokens/<server>.json (a non-canonical basename) stayed exposed. Added _is_sensitive_path() — a path-aware check that blocks any path with a credential-directory component — and routed all three call sites (list/read/download) through it.
    • Added .git-credentials to the basename set (agent.file_safety blocks it too).
    • Corrected the docstring: it now accurately says it mirrors the credential-file basenames, with the directory trees handled by the new path-aware helper (the prior wording overstated parity).

Scope stays on the read/list/download exfil surface (#57505). The write endpoints (upload/mkdir/delete) are a separate threat class and out of scope for this PR.

Validation

Before After
auth.json, .envrc, etc. via Files tab readable 403 / hidden
mcp-tokens/<server>.json on subdir descent readable 403 / hidden
.git-credentials readable 403 / hidden
benign subdir file (notes/todo.txt) readable still readable (positive control)
  • tests/hermes_cli/test_web_server_files.py — 26 passed (23 original + new dir-tree, .git-credentials, and benign-subdir positive-control tests).
  • Wider test_web_server_files.py + test_web_server_fs.py — 39 passed.
  • Mutation-checked: neutering _is_sensitive_path makes the new regression tests fail (guard genuinely enforced), restoring makes them pass.
  • ruff check clean.

Closes #57833. Credit to @srojk34 — their commit is cherry-picked with authorship preserved.

…t .env

_is_sensitive_filename() only blocked .env / .env.<suffix>, but the
dashboard Files tab's managed root is operator-configurable and, per the
docker-mount scenario NousResearch#57505 was filed against, can point directly at
HERMES_HOME — where the canonical credential stores enforced elsewhere
in the codebase (gateway.platforms.base._ROOT_CREDENTIAL_FILES,
agent.file_safety.get_read_block_error) all live: auth.json, OAuth
token stores, webhook HMAC secrets, the Bitwarden disk cache. None of
those basenames were blocked, so the Files tab could still list, read,
and download them. .envrc (direnv) also slipped past the old check
since it doesn't equal ".env" or start with ".env.".

Widen the basename set to mirror both existing guards so the dashboard
doesn't lag behind them.
@kshitijk4poor
kshitijk4poor force-pushed the salvage/dashboard-credential-guard branch from 17be186 to 8d80fc2 Compare July 4, 2026 11:10
@alt-glitch alt-glitch added type/security Security vulnerability or hardening comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P3 Low — cosmetic, nice to have needs-repro Bug needs reproduction steps labels Jul 4, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: salvage of #57833 (@srojk34) plus a follow-up that closes the directory-tree gap a basename-only guard left open (mcp-tokens/, pairing/). Part of the dashboard credential-guard cluster: #57833 (basename widen), #57865 (credential dirs), #57869 (/api/fs preview), #58034 (managed-file mutations), #58036 (git review diffs). This PR supersedes the read/list/download basename portion of #57833 and adds the path-aware directory check — a human should pick which of the overlapping reads-side PRs to merge.

@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: Comment

Summary

Security fix that widens the managed-files credential guard to cover more credential file basenames (auth.json, credentials, .git-credentials, etc.) and adds directory-level guards for mcp-tokens and pairing directories. Previously, the guard only covered .env variants.

Looks Good

  • Security improvement: covers more credential file types
  • Directory-level matching prevents exposure of nested credential stores
  • Consistent with agent.file_safety and gateway.platforms.base guards
  • Clear comment explaining the design
  • No security concerns in the implementation

Reviewed by Hermes Agent

…anaged-files guard

Follow-up to @srojk34's basename-denylist widening. Two gaps the
basename-only guard left, both covered by the two canonical guards it
mirrors:

- Directory-tree stores mcp-tokens/ (live MCP OAuth tokens) and pairing/
  are denied as whole trees by gateway.platforms.base._ROOT_CREDENTIAL_DIRS
  and agent.file_safety, but the dashboard files API descends into subdirs,
  so mcp-tokens/<server>.json (non-canonical basename) stayed
  listable/readable/downloadable. Add _is_sensitive_path(), a path-aware
  check that blocks any path with a credential-directory component, and
  route all three call sites (list/read/download) through it.
- Add .git-credentials to the basename set (agent.file_safety blocks it too).
- Correct the docstring: it now says it mirrors the credential-FILE basenames
  of the canonical guards, with the directory trees handled by the new
  path-aware helper (the prior wording overstated parity).

Scope stays on the read/list/download exfil surface (NousResearch#57505); the write
endpoints (upload/mkdir/delete) are a separate threat and out of scope.

Tests: dir-tree descent blocked (mcp-tokens/pairing per-server files),
.git-credentials blocked, plus a positive control that a benign subdir file
stays browsable. Mutation-checked (neuter _is_sensitive_path -> new tests
fail). 39 web_server_files + fs tests pass, ruff clean.
@kshitijk4poor
kshitijk4poor force-pushed the salvage/dashboard-credential-guard branch from 8d80fc2 to 8b24376 Compare July 4, 2026 12:28
@kshitijk4poor
kshitijk4poor enabled auto-merge July 4, 2026 12:28
@kshitijk4poor
kshitijk4poor merged commit e02fc28 into NousResearch:main Jul 4, 2026
29 checks passed
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…board-credential-guard

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…board-credential-guard

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…board-credential-guard

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap
@kshitijk4poor
kshitijk4poor deleted the salvage/dashboard-credential-guard branch August 5, 2026 07:10
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…board-credential-guard

security(dashboard): widen managed-files credential guard past .env + close dir-tree gap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/dashboard Web dashboard / control panel UI (dashboard/, landing) needs-repro Bug needs reproduction steps P3 Low — cosmetic, nice to have type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants