fix(security): tokenize the execute_bash destructive-command screen (#128) - #195
Open
rifkir23 wants to merge 1 commit into
Open
fix(security): tokenize the execute_bash destructive-command screen (#128)#195rifkir23 wants to merge 1 commit into
rifkir23 wants to merge 1 commit into
Conversation
…S#128) The execute_bash guard matched destructive commands as substrings of the raw command string. Even after whitespace normalization it stayed bypassable: split short flags (rm -r -f), long flags (rm --recursive --force), and numeric permission variants (chmod 0777) all slip through, while benign commands that merely contain the text (touch rm-rf-notes.txt) are falsely blocked. Replace it with core.harness.command_guard.screen_command, which splits the command on shell operators (; && || | &) and tokenizes each segment with shlex, matching on argv (command name + flags) instead of substrings. This closes the flag-order / flag-spelling / numeric gaps and also catches a destructive stage hidden in a pipeline or sequence (echo hi && rm -rf /). This is cheap defense-in-depth, not the security boundary: the workspace sandbox remains the real enforcement, and any command the screen cannot parse is passed through to it unchanged. Add tests/test_command_guard.py covering the historical bypasses, the old false-positives, multi-segment commands, empty input, and unparseable input.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #128.
Problem
The
execute_bashguard intools/code_implementation_server.pydecides whether a command is destructive by matching it as a substring of the raw command string:The whitespace-normalization that was already added here helps (
RM -rfno longer slips through), but a normalized substring check is still bypassable, and issue #128 explicitly kept this open to track it:rm -r -f /rm --recursive --force /chmod 0777 filetouch rm-rf-notes.txtSo the layer both misses real destructive commands and false-positives on harmless ones.
Change
Add
core/harness/command_guard.pywithscreen_command(command) -> str | None. It splits the command on the shell control operators (;&&|||&and newlines) and tokenizes each segment withshlex, then matches on the argv (command name + flags) rather than substrings. That:-rf,-fr,-r -f,--recursive --forceas equivalent (flag order / combination / spelling no longer matter);777,0777) and symbolic (a+rwx) chmod forms;echo hi && rm -rf /,cd /tmp; rm -rf build);execute_bashnow callsscreen_commandin place of the substring list.This is defense-in-depth, not the boundary
I have deliberately not touched the sandbox. As #128 concluded, the workspace sandbox in
core.harness.sandboxis the real enforcement; this screen is the cheap first pass in front of it. It never raises, and any command it cannot tokenize (unbalanced quotes, etc.) is passed straight through to the sandbox unchanged — the goal is to make the shallow layer honestly catch what it claims to, without pretending to be the boundary.Tests
tests/test_command_guard.pycovers the historical bypasses, the old false-positives, multi-segment commands, empty input, and unparseable input.ruff checkandruff format --checkare clean on the new and modified files.