Skip to content

Add tests for user-reported rm security bypass variants#48647

Merged
rtfeldman merged 4 commits intomainfrom
more-security-tests
Feb 6, 2026
Merged

Add tests for user-reported rm security bypass variants#48647
rtfeldman merged 4 commits intomainfrom
more-security-tests

Conversation

@rtfeldman
Copy link
Copy Markdown
Contributor

Builds on top of #48620 to add explicit test coverage for the exact bypass scenarios reported by users:

  • rm -rf /etc/../ — path traversal via single parent dir that normalizes to /
  • rm -rf --no-preserve-root / — long flag without =value that could bypass the old regex
  • rm --no-preserve-root -rf / — long flag positioned before short flags
  • rm / -rf --no-preserve-root — trailing long flag without =value after the path operand
  • sudo rm -rf /, sudo rm -rf /*, sudo rm -rf --no-preserve-root / — sudo-prefixed variants

All of these cases are already correctly blocked by the hardened regex patterns and path normalization logic added in #48620. These tests confirm that the reported bypasses are addressed and guard against regressions.

Release Notes:

  • N/A

- Add normalize_path function to resolve .., ., and redundant separators
- Add decide_permission_for_path wrapper that normalizes before checking
- Add expand_rm_to_single_path_commands to handle multi-path rm commands
- Normalize paths in rm commands before checking hardcoded security rules
- Normalize suffix after $HOME/${HOME} variable references
- Handle -- end-of-options marker in rm commands
- Handle trailing flags after path operand (GNU rm accepts this)
- Broaden FLAGS regex to accept digits, underscores, and uppercase
- Handle tabs/any whitespace after rm command name
- Preserve .. components that traverse above start path
- Preserve leading / for absolute paths in normalize_path
- Extensive test coverage for all edge cases
Add explicit test coverage for the exact bypass scenarios reported by users:

- `rm -rf /etc/../` (path traversal via single parent dir to root)
- `rm -rf --no-preserve-root /` (long flag without =value)
- `rm --no-preserve-root -rf /` (long flag before short flags)
- `rm / -rf --no-preserve-root` (trailing long flag without =value)
- `sudo rm -rf /` and `sudo rm -rf /*` (sudo prefix)

All these cases are already correctly blocked by the hardened regex
and path normalization logic in this branch; these tests confirm that.
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Feb 6, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label Feb 6, 2026
# Conflicts:
#	crates/agent/src/tool_permissions.rs
@rtfeldman rtfeldman marked this pull request as ready for review February 6, 2026 22:39
@rtfeldman rtfeldman enabled auto-merge (squash) February 6, 2026 22:39
@rtfeldman rtfeldman merged commit 38815c1 into main Feb 6, 2026
27 checks passed
@rtfeldman rtfeldman deleted the more-security-tests branch February 6, 2026 22:46
@KieranP
Copy link
Copy Markdown

KieranP commented Feb 6, 2026

@rtfeldman This doesn't appear to account for line separators (\) either, or subshells, among other things. rm -rf \/, \rm \-rf \/, /bin/bash -c 'rm -rf /', echo $(rm -rf /), etc. I appreciate the effort you're making, but trying to harden security in this way will never fully work, there will always be 100s of ways to bypass a regex.

The best approach would be to ensure the AI cannot make shell commands at all, and instead Zed provides various tools the AI can use that constrain any actions to the open workspace only. But that would require a lot of work to make every CLI tool (cat, ls, rm, mkdir, git, etc) a supported tool, but would give the best security and flexibility long term.

The other approach would be to use chroot before any AI executed commands to constrain all AI commands to the current working directory. https://wiki.archlinux.org/title/Chroot - The downside is that this often requires sudo to execute.

@rtfeldman
Copy link
Copy Markdown
Contributor Author

I appreciate the effort you're making, but trying to harden security in this way will never fully work, there will always be 100s of ways to bypass a regex.

@KieranP Totally agree - the goal here is really just to 80-20 address some things that are definitely banworthy.

@davc0n
Copy link
Copy Markdown

davc0n commented Feb 12, 2026

From #48209

Ideally, the agent would only allow changes within the working directory, I can't think of any good reason why running agents in my project should modify files/paths outside...

I agree with @KieranP's point here.

Restricting the agent to only allow changes within the working directory makes sense, as it minimizes the risk of unintended modifications outside the project scope.

If this could be implemented, it would be a great step forward imho.

naaiyy added a commit to Glass-HQ/Glass that referenced this pull request Feb 16, 2026
Key changes:
- LSP folding ranges support (zed-industries#48611) - textDocument/foldingRange with custom fold text
- LSP refactoring (zed-industries#48604) - extracted document_colors, code_lens, folding_ranges into modules
- Crate graph restructuring (zed-industries#48602) - terminal moved closer to editor
- Side-by-side diff searching (zed-industries#48539) and OpenExcerpts for LHS (zed-industries#48438)
- SplittableEditor: sync custom blocks between RHS/LHS (zed-industries#48575)
- Thinking effort for Zed/OpenAI providers (zed-industries#48545, zed-industries#48605)
- Agent default_model.enable_thinking setting (zed-industries#48536)
- Configurable LSP timeout setting (zed-industries#44745)
- PaneSearchBarCallbacks global (search bar setup extracted from vim)
- Settings migrations for nested platform/channel/profile keys (zed-industries#48550)
- Shell parser: I/O redirects, here-documents, compound commands (zed-industries#48635)
- Hardened tool authorization: sensitive settings, deferred ops (zed-industries#48641)
- rm security bypass fixes (zed-industries#48640, zed-industries#48647)
- MCP tool name parsing fix: newline delimiter (zed-industries#48636)
- Canonicalize --user-data-dir path (zed-industries#48470)
- Fix text_threads_dir XDG spec compliance (zed-industries#45771)
- Buffer font for folds (zed-industries#48652)
- Multibuffer toolbar layout shift fix (zed-industries#48472)
- Editor: tabs bitmask syncing (zed-industries#48366)

Conflict resolution:
- collab tests: deleted (collab removed)
- util/archive.rs, util/shell.rs: deleted (extracted to Obsydian)
- copilot_ui/sign_in.rs: kept native_button style
- editor_tests.rs: merged imports (kept MoveItemToPaneInDirection, added ViewId/FollowEvent)
- lsp_store.rs: took upstream refactored imports, added FoldingRangeData, removed collab imports
- main.rs: added PaneSearchBarCallbacks, removed vim::init

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants