[security] fix(workspace): restrict session workspaces to trusted roots (#416)

* fix(workspace): restrict session workspaces to trusted roots

* fix: use boot-time DEFAULT_WORKSPACE instead of profile default for trusted workspace root

_profile_default_workspace() reads the agent's terminal.cwd which may differ
from the WebUI's configured workspace root. Use _BOOT_DEFAULT_WORKSPACE (which
respects HERMES_WEBUI_DEFAULT_WORKSPACE for test isolation) to stay consistent
with how new_session() seeds the initial workspace.

* docs: v0.50.34 release — version badge and CHANGELOG

---------

Co-authored-by: hinotoi-agent <paperlantern.agent@gmail.com>
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
This commit is contained in:
nesquena-hermes
2026-04-13 23:44:03 -07:00
committed by GitHub
parent a5abe51cc5
commit 2a7a5ddfaf
9 changed files with 152 additions and 45 deletions

View File

@@ -107,14 +107,16 @@ def test_workspace_add_rejects_nonexistent():
assert status == 400
def test_workspace_add_accepts_real_dir():
"""Adding a real directory succeeds."""
import tempfile
tmp = tempfile.mkdtemp()
"""Adding a real directory under the trusted workspace root succeeds."""
d, _ = post("/api/session/new", {})
root = pathlib.Path(d["session"]["workspace"])
tmp = root / "trusted-add-test"
tmp.mkdir(parents=True, exist_ok=True)
try:
d, status = post("/api/workspaces/add", {"path": tmp, "name": "test-ws"})
d, status = post("/api/workspaces/add", {"path": str(tmp), "name": "test-ws"})
assert status == 200
assert d["ok"] is True
finally:
post("/api/workspaces/remove", {"path": tmp})
post("/api/workspaces/remove", {"path": str(tmp)})
import shutil
shutil.rmtree(tmp, ignore_errors=True)