Skip to content

gate: irrecoverable allows git -C${R} reset --hard (braced var glued to a git global); chmod rule over-blocks a 777 path #405

Closed

Description

@wasikarn

Found by the 2026-10-03 deep-audit of fea6ebd..2c3fffa (Codex checker, both reproduced independently at 2c3fffa with bash hooks/gates/irrecoverable.sh).

F1 (P1, bypass). A braced variable glued to a git global option is allowed, so destructive git commands pass. Exit 0 (should be 2): git -C${R} reset --hard, git -C${R} push --force origin main, git -C${R:-.} reset --hard. The unbraced forms are denied (git -C$R reset --hard, git -C"$R" ..., git --git-dir=${R} reset --hard all exit 2). The #383 _Glued fix (GH #375) did not cover this shape: hooks/gates/irrecoverable.py:1663-1688 (_git_words) joins glued runs, and :1984-1991 appends the re-read window only when it returns one. Find why the {...} part is not joined (likely {/} handling in _split_ops or _tokens), fix it in the same second-reading style (deny in either reading wins), and check the sibling walks from #382 are not affected twice. Needs its own differential (fixtures, transcript replay, fuzz) per docs/reference/repo-gotchas.md.

F2 (P3, over-block, fails closed). The chmod rule searches every argument for 777 or a+rwx (hooks/gates/irrecoverable.py:1717), so chmod -R 755 777 and chmod -R 755 a+rwx exit 2 although the mode is 755. Identify the mode argument (first non-option word, after --/-R etc.) and test only that; keep chmod -R 777 x denied.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions