fix(exec): extract absolute paths after equals sign in shell guard (#4594)

This commit is contained in:
AxelRay 2026-07-23 22:58:01 +07:00 committed by GitHub
parent 7e9426d9bd
commit 78f4c132d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 2 deletions

View File

@ -918,6 +918,6 @@ class ExecTool(Tool):
r"(?<![A-Za-z])(?:[A-Za-z]:[^\s\"'|><;]*|\\\\[^\s\"'|><;]+(?:\\[^\s\"'|><;]+)*)", r"(?<![A-Za-z])(?:[A-Za-z]:[^\s\"'|><;]*|\\\\[^\s\"'|><;]+(?:\\[^\s\"'|><;]+)*)",
command command
) )
posix_paths = re.findall(r"(?:^|[\s|>'\"])(/[^\s\"'>;|<]+)", command) # POSIX: /absolute only posix_paths = re.findall(r"(?:^|[\s|>='\"])(/[^\s\"'>;|<]+)", command) # POSIX: /absolute only
home_paths = re.findall(r"(?:^|[\s>'\"])(~[^\s\"'>;|<]*)", command) # POSIX/Windows home shortcut: ~ home_paths = re.findall(r"(?:^|[\s>='\"])(~[/+][^\s\"'>;|<]*)", command) # POSIX/Windows home shortcut: ~/ or ~+
return win_paths + posix_paths + home_paths return win_paths + posix_paths + home_paths

View File

@ -289,6 +289,19 @@ def test_exec_extract_absolute_paths_captures_home_paths() -> None:
assert "~/out.txt" in paths assert "~/out.txt" in paths
def test_exec_extract_absolute_paths_captures_paths_after_equals() -> None:
cmd = "curl --output=/etc/passwd --config=~/.nanobot/config.json"
paths = ExecTool._extract_absolute_paths(cmd)
assert "/etc/passwd" in paths
assert "~/.nanobot/config.json" in paths
def test_exec_extract_absolute_paths_does_not_capture_query_tilde() -> None:
cmd = 'python query.py --query \'{job=~"app"}\''
paths = ExecTool._extract_absolute_paths(cmd)
assert not any(p.startswith("~") for p in paths)
def test_exec_extract_absolute_paths_captures_quoted_paths() -> None: def test_exec_extract_absolute_paths_captures_quoted_paths() -> None:
cmd = 'cat "/tmp/data.txt" "~/.nanobot/config.json"' cmd = 'cat "/tmp/data.txt" "~/.nanobot/config.json"'
paths = ExecTool._extract_absolute_paths(cmd) paths = ExecTool._extract_absolute_paths(cmd)
@ -306,6 +319,15 @@ def test_exec_guard_blocks_home_path_outside_workspace(tmp_path) -> None:
assert "hard policy boundary" in error assert "hard policy boundary" in error
def test_exec_guard_blocks_equals_home_path_outside_workspace(tmp_path) -> None:
tool = ExecTool(restrict_to_workspace=True)
error = tool._guard_command("cat --config=~/.nanobot/config.json", str(tmp_path))
assert error is not None
assert error.startswith(
"Error: Command blocked by safety guard (path outside working dir)"
)
def test_exec_guard_blocks_quoted_home_path_outside_workspace(tmp_path) -> None: def test_exec_guard_blocks_quoted_home_path_outside_workspace(tmp_path) -> None:
tool = ExecTool(restrict_to_workspace=True) tool = ExecTool(restrict_to_workspace=True)
error = tool._guard_command('cat "~/.nanobot/config.json"', str(tmp_path)) error = tool._guard_command('cat "~/.nanobot/config.json"', str(tmp_path))