Commit Graph

5 Commits

  • fix(hooks): close subshell bypass in pre-bash-dev-server-block
    Before this commit the dev-server-block hook ran the leading-command
    and dev-pattern check only against the top-level segments returned by
    `splitShellSegments`, which doesn't split on `$(...)`, backticks, or
    plain `(...)`. That left the policy bypassable by wrapping a dev
    command in any of those constructs:
    
      $(npm run dev)
      `npm run dev`
      echo $(npm run dev)
      (npm run dev)
    
    Each verified by piping a synthetic PreToolUse payload into the hook
    on this branch: every form above returned exit 0 (allow) where a plain
    `npm run dev` correctly returned exit 2 (block).
    
    Fix: expand the check space before running the leading-command rule.
    A small BFS walks the raw command, harvesting bodies from
    `extractCommandSubstitutions` (`$(...)` and backticks) and from
    `extractSubshellGroups` (plain `(...)`), then splits each harvested
    body through `splitShellSegments` and feeds the result into the
    existing `isBlockedDevSegment` check.
    
    This preserves every existing allow case (`tmux new-session -d -s dev
    "npm run dev"`, quoted-string mentions like `git commit -m "npm run
    dev fix"`, `echo hi`) because the leading-command rule is unchanged —
    only the set of segments it runs against grew.
    
    Known limitation, not fixed here: `eval "$(echo npm run dev)"` still
    slips through because the substitution body's leading command is
    `echo`, and statically modeling echo's output to recover the executed
    command is out of scope. The same class affects `gateguard-fact-force`
    (via `eval "$(echo rm -rf /)"` etc.) and is best addressed in both
    hooks together as a follow-up rather than as a one-off here.
  • fix(hooks): allow tmux-wrapped dev server commands (#321)
    * fix(hooks): fix shell splitter redirection/escape bugs, extract shared module
    
    - Fix single & incorrectly splitting redirection operators (&>, >&, 2>&1)
    - Fix escaped quotes (\", \') not being handled inside quoted strings
    - Extract splitShellSegments into shared scripts/lib/shell-split.js
      to eliminate duplication between hooks.json, before-shell-execution.js,
      and pre-bash-dev-server-block.js
    - Add comprehensive tests for shell splitting edge cases
    
    * fix(hooks): handle backslash escapes outside quotes in shell splitter
    
    Escaped operators like \&& and \; outside quotes were still being
    treated as separators. Add escape handling for unquoted context.