Skip to content

Detectors miss bare wildcards (Bash(*)) and all colon-syntax rules (Bash(cmd:*)) — the riskiest grants pass as safe #11

Description

@AliceLJY

Thanks for building this — the "standing permission debt" angle is a real gap in the Claude Code tooling ecosystem, and the defensive engineering (loopback-only UI, symlink refusal, read-only ~/.claude.json) is impressive for a v0.1.0.

I ran audit --show-safe against a real, heavily-used config (183 allow rules across settings.json + settings.local.json, macOS) and found two systematic detection gaps where the most dangerous rules are the ones that pass as safe.

1. Bare wildcards are classified SAFE

from grantguard.core.detectors import apply_detectors

apply_detectors("Bash(*)")   # -> SAFE
apply_detectors("Skill(*)")  # -> SAFE

Bash(*) is the widest grant Claude Code supports — any shell command, forever. It should arguably be the single highest-severity finding in any audit, but it lands in the "Scoped / read-only / harmless" bucket. Meanwhile Bash(git *) is flagged OVERBROAD, which reads upside-down in the report: every scoped-but-broad rule gets flagged while the unscoped catch-all sails through.

2. Colon-syntax prefix wildcards (Bash(cmd:*)) are invisible to the detectors

apply_detectors("Bash(nc *)")        # -> OVERBROAD
apply_detectors("Bash(nc:*)")        # -> SAFE

apply_detectors("Bash(killall *)")   # -> OVERBROAD
apply_detectors("Bash(killall:*)")   # -> SAFE

apply_detectors("Bash(sudo cp:*)")   # -> SAFE
apply_detectors("Bash(crontab:*)")   # -> SAFE

Bash(cmd:*) and Bash(cmd *) are semantically equivalent prefix matchers in Claude Code's permission syntax — but only the space form is detected. This matters more than it looks: the colon form is what Claude Code itself writes when a user clicks "always allow", so rules accumulated organically through normal use are predominantly colon-syntax. In my run, all 42 colon-syntax command-family wildcards in settings.local.json passed as safe, including sudo-prefixed ones and persistence-capable commands like crontab.

Expected behavior

  • Bash(*) / Skill(*) / bare * variants flagged at the highest severity (arguably above OVERBROAD — there's no command family to reason about at all).
  • Colon syntax normalized to the same representation as space syntax before detectors run, so Bash(nc:*) and Bash(nc *) classify identically.

Happy to provide the full (redacted) audit output if useful. Tested on commit from 2026-07-08, Python 3.11, macOS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions