diff --git a/contributors/emails/290877921+pprism13@users.noreply.github.com b/contributors/emails/290877921+pprism13@users.noreply.github.com new file mode 100644 index 0000000000..5655bdd2db --- /dev/null +++ b/contributors/emails/290877921+pprism13@users.noreply.github.com @@ -0,0 +1,2 @@ +pprism13 +# PR #41071 salvage diff --git a/tests/gateway/test_platform_base.py b/tests/gateway/test_platform_base.py index 207eec6543..03d5c3e32d 100644 --- a/tests/gateway/test_platform_base.py +++ b/tests/gateway/test_platform_base.py @@ -678,6 +678,34 @@ class TestMediaDeliveryDefaultMode: assert BasePlatformAdapter.validate_media_delivery_path(str(artifact)) == str(artifact.resolve()) + def test_denylist_blocks_session_stores_but_not_neighbouring_artifacts(self, tmp_path, monkeypatch): + """The SQLite session/kanban stores (and WAL/SHM sidecars, whose mtime is always fresh), + legacy ``sessions/`` transcripts and the copied browser cookie store hold every secret ever + pasted into a chat; ``MEDIA:~/.hermes/state.db`` must not exfiltrate them (#41071). Named + boards keep their DB beside the ATTACHMENTS the gateway already allowlists, so the board + attachment stays deliverable while ``kanban.db`` next to it does not.""" + self._patch_roots(monkeypatch) + + fake_home = tmp_path / "home" + hermes_dir = fake_home / ".hermes" + hermes_dir.mkdir(parents=True) + monkeypatch.setenv("HOME", str(fake_home)) + monkeypatch.setattr("gateway.platforms.base._HERMES_HOME", hermes_dir) + monkeypatch.setattr("gateway.platforms.base._HERMES_ROOT", hermes_dir) + board = hermes_dir / "kanban" / "boards" / "team-a" + (board / "attachments").mkdir(parents=True) + + denied = ["state.db", "state.db-wal", "state.db-shm", "kanban.db", "kanban.db-wal", + "sessions/20260101_abc.json", "browser-profile/Default/Cookies", + "kanban/boards/team-a/kanban.db", "kanban/boards/team-a/kanban.db-wal"] + allowed = ["kanban/boards/team-a/attachments/report.pdf", "adhoc_report.pdf", "logs/agent.log"] + for rel in denied + allowed: + path = hermes_dir / rel + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(b"SQLite format 3\x00") + assert [rel for rel in denied if BasePlatformAdapter.validate_media_delivery_path(str(hermes_dir / rel))] == [] + assert [rel for rel in allowed if not BasePlatformAdapter.validate_media_delivery_path(str(hermes_dir / rel))] == [] + def test_strict_mode_envvar_restores_legacy_behavior(self, tmp_path, monkeypatch): """Setting HERMES_MEDIA_DELIVERY_STRICT=1 reactivates the older allowlist+recency logic. A stale file outside the allowlist is @@ -1553,3 +1581,4 @@ class TestPlatformLockTakeoverGovernance: assert adapter._acquire_platform_lock("discord-token", "tok", "Discord") is False assert len(takeover_calls) == 1 assert adapter._platform_lock_takeover_attempted is True +