Skip to content

[Feature]: harden read-only bash classifier (fd redirects, globs, find -exec) #428

Description

@jexShain

Summary

Harden the read-only bash classifier so it stops blocking harmless inspection commands and stops letting a real write through as "read-only".

Use case

Sub-agents run inside a read-only bash sandbox. The classifier currently has two correctness gaps:

  1. False positives (over-blocking) — safe commands are rejected as non-read-only, forcing unnecessary confirmation or failing the sub-agent:

    • ls 2>&1, cat foo 2>&12>&1 duplicates a file descriptor; the & was mistaken for a background operator or write redirect.
    • ls *.txt — unquoted globs were blocked, even though glob expansion never mutates the filesystem.
    • find . -exec grep foo {} \;-exec was blanket-blocked regardless of the embedded command.
  2. False negative (under-blocking / security)>&word where word is not a digit redirects stdout to a file in bash (verified: echo x >& /tmp/f writes the file), but the new >& allowance treated every >& as fd duplication and classified echo x >& /tmp/f as read-only. That bypasses the sub-agent's only filesystem-write gate.

Proposed solution

  • fd redirects: treat >&N (digit, e.g. 2>&1, >&2) and >&- (close) as read-only fd duplication; treat >&word (non-digit) as a write redirect so echo x >& /tmp/f is blocked. Same fix applied in split_compound_segments and has_background_operator so 2>&1 is not split or misread as a background job.
  • globs: allow unquoted globs — writes like rm *.txt / cp *.x /d are still caught by the blocked-command list, and echo *.x > f by the write-redirect check.
  • find -exec: recursively classify the embedded command — find -exec grep/wc/head {} \; passes, find -exec rm {} \; is blocked; -delete stays destructive. Handles both \; and + terminators.

Alternatives considered

  • Keep blocking globs and find -exec outright — leaves sub-agents unable to run ordinary inspection commands, defeating the point of a read-only sandbox.
  • Whitelist specific find -exec commands — brittle and maintenance-heavy; recursive classification is general.

Additional context

Regression tests added: 2>&1/>&2/>&- read-only; >& /tmp/f, >&/tmp/f, >& f blocked; find -exec rm blocked, find -exec grep allowed; unquoted glob allowed. The >&word write bypass was caught during review of the fd-redirect support and is fixed in the same change rather than shipped as a hole.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ci-cdCI/CD workflow issueenhancementNew feature or requestptyPTY or interactive process issuesecuritySecurity-related issuetestsTest coverage or test failure issuetoolsTool integration issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions