mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(security): validate snapshot_id and file paths in restore_quick_snapshot to prevent path traversal
This commit is contained in:
parent
a6f07a6c37
commit
8a5f302b3a
1 changed files with 28 additions and 1 deletions
|
|
@ -574,8 +574,22 @@ def restore_quick_snapshot(
|
|||
"""
|
||||
home = hermes_home or get_hermes_home()
|
||||
root = _quick_snapshot_root(home)
|
||||
|
||||
# Security: reject snapshot_id values that contain path separators or
|
||||
# traversal sequences so that `root / snapshot_id` stays inside root.
|
||||
if not snapshot_id or "/" in snapshot_id or "\\" in snapshot_id or snapshot_id in (".", ".."):
|
||||
logger.error("Invalid snapshot_id: %s", snapshot_id)
|
||||
return False
|
||||
|
||||
snap_dir = root / snapshot_id
|
||||
|
||||
# Confirm the resolved path is still inside root (handles symlinks etc.)
|
||||
try:
|
||||
snap_dir.resolve().relative_to(root.resolve())
|
||||
except ValueError:
|
||||
logger.error("Snapshot path traversal blocked for id: %s", snapshot_id)
|
||||
return False
|
||||
|
||||
if not snap_dir.is_dir():
|
||||
return False
|
||||
|
||||
|
|
@ -588,11 +602,24 @@ def restore_quick_snapshot(
|
|||
|
||||
restored = 0
|
||||
for rel in meta.get("files", {}):
|
||||
# Security: reject absolute paths and traversals in manifest entries
|
||||
src = snap_dir / rel
|
||||
if not src.exists():
|
||||
try:
|
||||
src.resolve().relative_to(snap_dir.resolve())
|
||||
except ValueError:
|
||||
logger.error("Manifest path traversal blocked: %s", rel)
|
||||
continue
|
||||
|
||||
dst = home / rel
|
||||
try:
|
||||
dst.resolve().relative_to(home.resolve())
|
||||
except ValueError:
|
||||
logger.error("Manifest path traversal blocked: %s", rel)
|
||||
continue
|
||||
|
||||
if not src.exists():
|
||||
continue
|
||||
|
||||
dst.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue