mirror of
https://github.com/usestrix/strix.git
synced 2026-08-25 12:22:37 +02:00
fix(safety): close three evidence bypasses and make workspace staging idempotent
Grouped browser verbs were classified by their verb alone. `tab` and `session` sit in the passive set, so `tab new <url>` — documented as navigating — and `session clear` earned a deterministic allow and executed unreviewed in guarded mode and unblocked in observe, while `open <url>`, the same navigation, was reviewed. Passivity is now decided from verb plus subcommand, and the packet carries the result so observe mode stops maintaining a second copy of the rule that could drift more permissive than guarded. The blocked-action list still matches on the bare verb, so `auth login` keeps matching `auth`. Interpreters were a seven-name allowlist, so `python3.12`, `/usr/bin/python3`, `php`, and `deno` set no script path and produced a packet with no artifacts that was still stamped complete — the exact shape the reviewer is told it may allow. Recognize versioned and common interpreters so their sources are actually collected, and fail closed when a command runs code that cannot be resolved to an inspectable script. `from pkg import payload` collected only the package initializer, because an imported name was treated as an attribute and never as a submodule. Effectful code in `pkg/payload.py` executed without appearing in the evidence. Workspace staging runs twice per run and was not idempotent: the second pass read the origin from `source_path`, which the first pass had already rewritten to the copy. With the completion marker absent it cleared the destination and then copied from that same emptied directory, silently handing the agent an empty workspace. The origin is now read back from `original_source_path`. Each fix is covered by a test that fails when the fix is reverted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,6 +47,11 @@ read-only commands is allowed outright, but only when its options are also
|
||||
read-only: `rg --pre` and anything else that hands the command another program
|
||||
to run goes to review instead.
|
||||
|
||||
Browser observation commands are allowed outright only in the form that just
|
||||
reads: `tab` lists tabs, but `tab new <url>` navigates and `tab close` discards
|
||||
page state, so a grouped verb with a subcommand goes to review and is blocked
|
||||
in `observe`.
|
||||
|
||||
Commands that wrap another program (`sudo`, `timeout`, `xargs`, `nohup`, and
|
||||
similar) and interactive `write_stdin` payloads cannot be resolved to a single
|
||||
effective action before dispatch, so they are blocked. Issue the command as its
|
||||
@@ -57,12 +62,17 @@ own `exec_command` call.
|
||||
When a command executes a script, Strix reads the current entrypoint and local
|
||||
Python imports without importing or running them. Inline `python -c` source is
|
||||
analyzed the same way. Absolute imports resolve against the entrypoint's
|
||||
directory and relative imports against the importing module's package, so the
|
||||
whole local closure is inspected. Decisions bind to content hashes. Dynamic
|
||||
code execution, import-path mutation, unresolved generated commands, oversized
|
||||
directory and relative imports against the importing module's package, and an
|
||||
imported name is followed as a submodule as well as an attribute, so the whole
|
||||
local closure is inspected. Decisions bind to content hashes. Dynamic code
|
||||
execution, import-path mutation, unresolved generated commands, oversized
|
||||
dependency closures, entrypoints outside `/workspace`, and unsupported evidence
|
||||
block the action.
|
||||
|
||||
A command that runs code Strix cannot resolve to an inspectable script — an
|
||||
unrecognized interpreter, or an interpreter given no script — is blocked rather
|
||||
than reviewed against an empty evidence packet.
|
||||
|
||||
Browser automation inside scripts is blocked in safety modes. Issue browser
|
||||
operations as individual raw `agent-browser` commands so each action can be
|
||||
reviewed against the current snapshot and element references.
|
||||
|
||||
Reference in New Issue
Block a user