fix(dashboard): guard git review credential mutations - #58040
Conversation
|
suggesting changes The new filter still lets the review commit endpoint commit credential contents when a protected path is renamed or copied to a safe-looking path. Security evidence: authenticated dashboard Git/review API calls can issue git mutations inside a user-selected repository; protected credential path contents must not be staged or committed by the review API even when Git reports a rename/copy with a non-protected destination; current main is vulnerable to bulk Signed: GPT-5.5-xhigh in Codex |
|
Priority corrected: P1 → P3 (triage calibration). Assessed against the repo The dashboard is loopback-by-default and its caller is the operator/agent already Keeping |
|
Updated the branch to handle rename/copy origins on the mutation path too. review_commit now checks staged protected rename/copy origins before committing, and auto-stage only stages changed entries whose full path set is safe. A tracked .env renamed to safe.txt is now rejected instead of being committed under the safe-looking destination. Validation: |
|
suggesting changes The update fixes the staged Security evidence:
Signed: GPT-5.5-xhigh in Codex |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for extending the guard to porcelain-v2 rename origins. The current-main premise is real: review_commit() still invokes git add -A when nothing is staged (hermes_cli/web_git.py:364-369).
Problems
- Blocking: the PR still auto-stages a safe-looking destination after a plain filesystem move.
_walk_entries_with_paths()records an origin only for tag2(hermes_cli/web_git.py:223-228), butreview_commit()stages every_safe_changed_paths()result (hermes_cli/web_git.py:440-443). A protected tag-1deletion plus untrackedsafe.txttherefore leavessafe.txteligible. - The same helper drives bulk stage and revert (
hermes_cli/web_git.py:403,417), so the gap is not commit-only. - The added regression test covers
git mvonly (tests/hermes_cli/test_web_server_git.py:163-182), not the deletion-plus-untracked status shape.
Suggested changes
- Make the batch policy fail closed for protected-deletion/untracked-destination cases across stage, revert, and auto-stage commit.
- Add a real-repo test using a filesystem move and assert
safe.txtis not staged, committed, or deleted.
Automated hermes-sweeper review.
| ): | ||
| raise PermissionError("Git review cannot commit protected credential files") | ||
| if not any(_entry_staged(tag, xy) for tag, xy, _path, _paths in entries): | ||
| paths = _safe_changed_paths(cwd) |
There was a problem hiding this comment.
_safe_changed_paths() cannot recognize a plain filesystem move: porcelain reports the old protected path as a tag-1 deletion and the safe-looking destination as ?, so this stages the destination. Please handle that batch shape and add a regression test before using this list for auto-stage.
Summary
The dashboard Git/review API could mutate credential files through the coding rail/review pane.
Affected routes:
POST /api/git/review/stagePOST /api/git/review/revertPOST /api/git/review/commitCurrent behavior on main:
review_stage(".env")runsgit add -- .envreview_revert(".env")runsgit clean -fd -- .env, deleting an untracked credential filereview_commit()auto-stages everything withgit add -Awhen nothing is staged, which can commit.envinto git historyWhy
Dashboard file browser/read/write hardening now treats credential paths as protected, but the Git review API is a separate surface. It can stage, commit, or delete those same files without passing through the file safety guards.
This creates credential leakage and credential-destruction risk from an authenticated dashboard/desktop review flow.
Changes
hermes_cli/web_git.pyusing:agent.file_safety.get_read_block_error()agent.file_safety.is_write_denied()git add -Awith staging only non-protected changed paths..env.env.envTests