Skip to content

feat: block semicolon and newline chaining in no-chaining hook #32

Description

@josephfung

Idea

Extend the no-chaining hook to block ; and newline-based command chaining the same way it currently blocks && and ||. Today, semicolons and newlines are allowed because shell constructs like for/do/done and if/then/fi require them. But they have the exact same permission-bypass risk as && — a command like ls; rm -rf / auto-approves based on ls at the start.

Why this is safe to do now

This is blocked by #31 (trimkit-symlink). The primary reason semicolons are allowed today is the worktree symlink loop pattern:

MAIN=/path/to/main WORKTREE=/path/to/wt; for item in .env; do ln -sf "$MAIN/$item" "$WORKTREE/$item"; fi

Once trimkit-symlink replaces this with a flat command, the main use case for semicolons in Bash tool calls goes away. Any remaining legitimate multi-statement needs can be handled with multi-line commands (which should also be analyzed) or multiple Bash tool calls.

What to block

  • Semicolons (;) outside of quoted strings — same stripping logic the hook already uses for &&/||
  • Newlines used to sequence independent commands — this is trickier since newlines are also structural (e.g., heredocs, multi-line strings). Needs careful design to distinguish echo "hello\nworld" from ls\nrm -rf /

Design considerations

  • Newline analysis is harder than semicolon analysis. Consider starting with semicolons only and deferring newline chaining to a follow-up if the detection logic is complex.
  • The hook already strips quoted strings before checking for operators — the same approach works for semicolons.
  • Need to audit existing allowed patterns and CLAUDE.md examples to ensure nothing legitimate breaks.
  • The for/do/done and if/then/fi constructs that currently rely on semicolons would need to be rewritten with newlines in any documentation or templates — but if newlines are also being blocked, these constructs need an exemption or a different approach.

Acceptance criteria

  • ; outside quoted strings is blocked with the same mechanism as &&
  • Newline chaining is either blocked or explicitly deferred to a follow-up issue with documented rationale
  • Existing tests updated — semicolon-based commands that currently pass should now be blocked
  • New tests for the semicolon blocking
  • CLAUDE.md template updated to remove "semicolons are allowed" section
  • No regression in legitimate single-operation commands

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions