fix(hermes_state): ensure state.db created with 0o600 permissions, not 0o644 umask default - #59717
Closed
liuhao1024 wants to merge 1 commit into
Closed
Conversation
Collaborator
Duplicate of #59716 (earliest-open twin, created ~2s earlier) — both fix issue #59706 at the same site ( |
- Move tests/test_hermes_state_permissions.py to tests/hermes_state/test_permissions.py - Add 'import os' to hermes_state.py (missing from original PR) - Remove sys.path manipulation from test file Fixes CI failures in PR NousResearch#59717.
liuhao1024
force-pushed
the
liuhao/cron-bugfix-59706-state-db-permissions
branch
from
July 6, 2026 15:51
821d3e3 to
4871b30
Compare
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Before this fix,
state.dbwas created bysqlite3.connect()with the process umask (usually 0o022), landing at 0o644 (world-readable). On defaultHERMES_HOME=0700this is inert (directory traversal blocks access), but it becomes load-bearing whenHERMES_HOME_MODEis wider (e.g., 0o755 for web-server traversal use cases) or in managed mode (NixOS sets it to 0o750). In these scenarios, other local accounts on the same host can read the full conversation history stored in state.db.This fix follows the TOCTOU-safe pattern already used for
auth.jsoninhermes_cli/auth.py:sqlite3.connect()touches the file, we create it withos.open(O_CREAT | O_EXCL, 0o600)to avoid umask-based permissions.exists()check andos.open()), we chmod it to 0o600.apply_wal_with_fallback()sets WAL mode, we chmod the-waland-shmsidecars to 0o600, since SQLite creates them at the process umask and they hold recent uncommitted writes.The fix is a security hardening measure: even if the parent directory has wider permissions, the database file itself is not world-readable.
Related Issue
Fixes #59706
Type of Change
Changes Made
hermes_state.py: Pre-createstate.dbwith 0o600 inSessionDB._connect_and_init()beforesqlite3.connect(); chmod existing files; chmod-wal/-shmsidecars after WAL mode is applied.tests/test_hermes_state_permissions.py: Add regression tests for:How to Test
Reproduce the bug (before the fix):
Verify the fix:
cd /tmp/hermes-bugfix-Mrc2jN python3 -m pytest tests/test_hermes_state_permissions.py -vExpected: All 3 tests pass, confirming:
state.dbis created with 0o600 permissionsManual verification:
Observed result: All files show 0o600 permissions, not 0o644 (umask default).
Checklist
Code
fix(scope):,feat(scope):, etc.)Documentation & Housekeeping
os.chmodis a no-op on Windows but the fix still provides defense-in-depth on Unix-like systems