mirror of
https://github.com/andrewyng/openworker.git
synced 2026-10-31 03:05:33 +00:00
fix(security): refuse find's fprint family under a bare allowlist entry
_DANGEROUS_FLAGS gates the flags that turn a search/list tool into an execution, deletion, or file-writing tool, so an allowlisted command can never auto-run them. It listed -fprintf but omitted -fprint, -fprint0, and -fls, which write find's output to an arbitrary path: with allowed_commands = ["find"], a plain name search auto-ran as intended but "find . -fprint /tmp/exfil.txt" also auto-ran, writing outside the workspace with no approval prompt. readonly.py's _FIND_BAD already carries the complete set for its own classifier; the allowlist denylist was the incomplete copy. Add the three flags so the two stay in step, and add a regression test beside the allowlist tests. Tests: an allowlisted name search still auto-runs; the fprint/fls forms now require approval.
This commit is contained in:
@@ -39,8 +39,11 @@ _INTERPRETERS = {
|
||||
"sh", "bash", "zsh", "dash", "ksh", "fish", "powershell", "pwsh", "cmd",
|
||||
"python", "python3", "node", "deno", "bun", "ruby", "perl", "php",
|
||||
}
|
||||
# Flags that turn a search/list tool into an execution or deletion tool.
|
||||
_DANGEROUS_FLAGS = {"-exec", "-execdir", "-delete", "-ok", "-okdir", "-fprintf"}
|
||||
# Flags that turn a search/list tool into an execution, deletion, or file-writing tool.
|
||||
# The fprint family writes find's output to an arbitrary path; omitting it let a bare
|
||||
# `find` allowlist entry auto-run `find . -fprint /tmp/exfil.txt`. readonly.py's
|
||||
# `_FIND_BAD` is the complete copy of this set, so keep the two in step.
|
||||
_DANGEROUS_FLAGS = {"-exec", "-execdir", "-delete", "-ok", "-okdir", "-fprintf", "-fprint", "-fprint0", "-fls"}
|
||||
|
||||
|
||||
def _split_commands(command: str) -> list[str]:
|
||||
|
||||
@@ -108,6 +108,20 @@ def test_exec_uses_command_allowlist(tmp_path):
|
||||
assert not asked.allowed and asked.needs_user
|
||||
|
||||
|
||||
def test_allowlisted_find_refuses_output_writing_flags(tmp_path):
|
||||
# `find`'s fprint family writes to an arbitrary path. A bare `find` allowlist entry
|
||||
# must not auto-run it, exactly as it already refuses -exec/-delete/-fprintf.
|
||||
eng = PermissionEngine(workspace_root=tmp_path, allowed_commands=["find"])
|
||||
assert eng.evaluate("run_shell", {"command": "find . -name '*.py'"}, None).allowed
|
||||
for command in (
|
||||
"find . -fprint /tmp/exfil.txt",
|
||||
"find . -fprint0 /tmp/exfil.txt",
|
||||
"find . -fls /tmp/exfil.txt",
|
||||
):
|
||||
d = eng.evaluate("run_shell", {"command": command}, None)
|
||||
assert not d.allowed and d.needs_user, command
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"command",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user