diff --git a/agent-node/VERSION b/agent-node/VERSION index 8fc77d0..f8f3c08 100644 --- a/agent-node/VERSION +++ b/agent-node/VERSION @@ -1 +1 @@ -1.0.17 +1.0.18 diff --git a/agent-node/src/agent_node/node.py b/agent-node/src/agent_node/node.py index 4b6efac..c6e4468 100644 --- a/agent-node/src/agent_node/node.py +++ b/agent-node/src/agent_node/node.py @@ -461,12 +461,17 @@ def _handle_fs_write(self, session_id, rel_path, content, is_dir, task_id=""): """Modular FS Write/Create.""" try: - base_dir = self._get_base_dir(session_id, create=True) + base_dir = os.path.normpath(self._get_base_dir(session_id, create=True)) target_path = os.path.normpath(os.path.join(base_dir, rel_path)) print(f" [📁💾] target_path: {target_path} (base_dir: {base_dir})") - if not target_path.startswith(base_dir): - raise Exception(f"Path traversal attempt blocked: {target_path} is outside {base_dir}") + # M6: Check if path is within session base_dir OR global FS_ROOT + allowed = target_path.startswith(base_dir) + if not allowed and FS_ROOT: + allowed = target_path.startswith(os.path.normpath(FS_ROOT)) + + if not allowed: + raise Exception(f"Path traversal attempt blocked: {target_path} is outside {base_dir} (FS_ROOT: {FS_ROOT})") if is_dir: os.makedirs(target_path, exist_ok=True) @@ -497,11 +502,15 @@ def _handle_fs_delete(self, session_id, rel_path, task_id=""): """Modular FS Delete.""" try: - base_dir = self._get_base_dir(session_id) - + base_dir = os.path.normpath(self._get_base_dir(session_id)) target_path = os.path.normpath(os.path.join(base_dir, rel_path)) - if not target_path.startswith(base_dir): - raise Exception("Path traversal attempt blocked") + + allowed = target_path.startswith(base_dir) + if not allowed and FS_ROOT: + allowed = target_path.startswith(os.path.normpath(FS_ROOT)) + + if not allowed: + raise Exception(f"Path traversal attempt blocked: {target_path} is outside {base_dir} (FS_ROOT: {FS_ROOT})") if not os.path.exists(target_path): raise Exception("File not found") @@ -533,11 +542,15 @@ def _push_file(self, session_id, rel_path, task_id=""): """Pushes a specific file from node to server.""" - watch_path = self._get_base_dir(session_id, create=False) - + watch_path = os.path.normpath(self._get_base_dir(session_id, create=False)) abs_path = os.path.normpath(os.path.join(watch_path, rel_path)) - if not abs_path.startswith(watch_path): - print(f" [📁🚫] Blocked traversal attempt in _push_file: {rel_path}") + + allowed = abs_path.startswith(watch_path) + if not allowed and FS_ROOT: + allowed = abs_path.startswith(os.path.normpath(FS_ROOT)) + + if not allowed: + print(f" [📁🚫] Blocked traversal attempt in _push_file: {rel_path} (Valid Roots: {watch_path}, FS_ROOT: {FS_ROOT})") return if not os.path.exists(abs_path):