From 5c9cb3a208a0a9b3e543c510753269073579adaa Mon Sep 17 00:00:00 2001 From: andienguyen-ecoligo Date: Sat, 21 Feb 2026 12:34:14 -0500 Subject: [PATCH] fix(security): prevent path traversal bypass via startswith check `startswith` string comparison allows bypassing directory restrictions. For example, `/home/user/workspace_evil` passes the check against `/home/user/workspace` because the string starts with the allowed path. Replace with `Path.relative_to()` which correctly validates that the resolved path is actually inside the allowed directory tree. Fixes #888 --- nanobot/agent/tools/filesystem.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nanobot/agent/tools/filesystem.py b/nanobot/agent/tools/filesystem.py index 9c169e4..b87da11 100644 --- a/nanobot/agent/tools/filesystem.py +++ b/nanobot/agent/tools/filesystem.py @@ -13,8 +13,11 @@ def _resolve_path(path: str, workspace: Path | None = None, allowed_dir: Path | if not p.is_absolute() and workspace: p = workspace / p resolved = p.resolve() - if allowed_dir and not str(resolved).startswith(str(allowed_dir.resolve())): - raise PermissionError(f"Path {path} is outside allowed directory {allowed_dir}") + if allowed_dir: + try: + resolved.relative_to(allowed_dir.resolve()) + except ValueError: + raise PermissionError(f"Path {path} is outside allowed directory {allowed_dir}") return resolved