Skip to content

gate: subagent guard misses an escape that only appears after eval or a double-quoted shell body parses the text again #327

Closed

Description

@wasikarn

Found by the #317 differential fuzz (pre-existing; develop allows every one of these too).

The #317 fix reads a backslash before an ordinary character the way one shell parse does. Two shapes parse the text twice, so a backslash pair that is a literal backslash after the first parse becomes an escape in the second one, and the subagent guard does not see the resulting git word:

  • unquoted eval: eval joins its parsed arguments and parses them again. eval g\\\it stash gives eval the word g\it, which runs git stash; eval nice\ git -C . reset gives it nice git -C . reset.
  • a double-quoted shell body: inside "..." the outer shell turns \\ into \ (and \$, \", a backtick escape), and the inner shell parses the result. bash -c "g\\it stash" runs git stash.

75 of the 108 branch false-allows in the #317 fuzz (4000 cases, real sh, bash 3.2, bash 5, dash, zsh, ksh as the oracle) are this shape; the other 33 are #320.

Fix direction: for a double-quoted body, undo the double-quote escapes (\\, \$, \`, \", backslash-newline) before the body is masked; for unquoted eval, scan its argument text a second time after one round of escape removal (any deny wins). Fuzz per docs/reference/repo-gotchas.md.

Activity

  1. self-assigned this
    on Oct 2, 2026
  2. added a commit that references this issue on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions