anthropics / anthropics/claude-code

Bash permission allow-rules: literal '*' inside quoted regex/glob arguments is silently reinterpreted as a positional wildcard on replay

Open
#95,614 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:permissions area:security bug has repro platform:wsl
Dominant language
TypeScript
Stars
147k
Forks
24k
PR merge metrics
PR metrics pending

Description

Summary
When a Bash command containing a literal * inside a quoted argument (e.g. a grep regex like "onclick.*Tab", or a glob like "*.py") is approved via "always allow", the resulting settings.local.json rule stores the * as-is. On replay, Claude Code's permission matcher treats every * in the stored string as its own positional wildcard — regardless of whether it originated inside quotes as a literal/regex character — allowing arbitrary content to be inserted at that position on future matches, as long as the literal suffix after it still occurs later in the command.

Why this matters
* is the universal wildcard/glob character across shells, OSes, and regex engines. Any user approving a one-off command that happens to contain a regex .* or a glob *.ext in a quoted argument unknowingly creates an allow-rule with an unintended insertion point — with no warning, no escaping mechanism, and no distinction between "wildcard meant as permission scope" vs. "literal character that happened to appear in quoted content."

This is a real-world instance of the same class of problem as #51057 (skill-level command normalization not matching the actual matcher semantics) — here at the core permission-matching layer itself.

Repro

  1. Run a Bash command with a quoted regex containing .*, e.g.:
    grep -n "onclick.*Tab" somefile.html
  2. Approve it with "always allow".
  3. Inspect the resulting rule in .claude/settings.local.json — the * from the regex is stored raw, at a position that is not at the end of the pattern and not preceded by a space (contradicting the project's own documented safe-wildcard guidance: wildcards should only appear at the end, preceded by a space, per the fewer-permission-prompts skill instructions).
  4. Any future command that reproduces the literal prefix/suffix around that * — with arbitrary content (including shell metacharacters ;, &&, $(), backticks) spliced into the wildcard's position — matches this rule and is auto-approved without a permission prompt.

Suggested fixes (any of these would resolve it)

  • Warn the user at approval time if the literal command contains a * inside a quoted argument, and offer to store the rule with that character escaped/treated as literal.
  • Use a non-colliding placeholder syntax for the permission engine's own wildcard (e.g. a dedicated token) instead of overloading *, which already carries context-dependent meaning in shells and regexes, and provides no logic to distinguish "wildcard meant as a stand-in for a specific word/pattern" from "the engine's own approval-scope wildcard."
  • At minimum, restrict stored allow-rules to only support wildcards in the documented safe position (end of pattern, preceded by a space) and reject/flag any other * occurrence as literal by default.

Environment: Claude Code CLI, discovered on Linux (WSL2), reproduced via the standard "always allow" approval flow — not linked to any specific plugin.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Claude Code CLI's standard "always allow" approval flow and the permission matcher that replays rules from .claude/settings.local.json. Reproduce the quoted * cases from the issue, then trace how stored wildcards are interpreted and add coverage showing that quoted literal characters cannot become unintended insertion points while documented permission wildcards still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authorization, cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.