From 0776ccb7c6b9e3349596ca0da2c2fa95b8a3aa16 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Fri, 15 May 2026 13:02:01 +0000 Subject: [PATCH] fix(security): use relative_to instead of startswith in inline_executor sandbox validation Replace string-based startswith check in InlineToolExecutor._validate_paths() with Path.relative_to() to prevent prefix-collision bypass attacks. The previous implementation using str(target).startswith(str(root)) without a path separator suffix was vulnerable to attacks such as: root=/tmp/sandbox, target=/tmp/sandbox_malicious/file.py where the target would incorrectly pass the startswith check despite escaping the sandbox root. --- src/cleveragents/skills/inline_executor.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cleveragents/skills/inline_executor.py b/src/cleveragents/skills/inline_executor.py index b85b69378..b10ce08d2 100644 --- a/src/cleveragents/skills/inline_executor.py +++ b/src/cleveragents/skills/inline_executor.py @@ -263,13 +263,15 @@ class InlineToolExecutor: try: resolved = Path(value).resolve() sandbox_resolved = sandbox_path.resolve() - if not str(resolved).startswith(str(sandbox_resolved)): - return ( - f"Path '{value}' for key '{key}' escapes sandbox " - f"root '{sandbox_path}'" - ) - except (OSError, ValueError): - return f"Invalid path '{value}' for key '{key}'" + except OSError as exc: + return f"Invalid path '{value}' for key '{key}': {exc}" + try: + resolved.relative_to(sandbox_resolved) + except ValueError: + return ( + f"Path '{value}' for key '{key}' escapes sandbox " + f"root '{sandbox_path}'" + ) return None def _run_with_timeout(