Guard the command shape, not the model’s intent
Use
when:
Claude
Code
native
builds
on
macOS
or
Linux
may
run
agent-written
Bash
searches,
especially
context-extraction
patterns
such
as
[^.]{0,110}keyword[^.]{0,90}.
Since
v2.1.117,
plain
grep
inside
the
Bash
tool
can
be
a
shell
function
that
re-executes
Claude
Code’s
embedded
ugrep,
not
the
system
binary.
PreToolUse
hook
with
"matcher":"Bash"
and
"command":"python3
~/.claude/hooks/block-regex-bomb.py".
The
parser
must
inspect
.tool_input.command
with
shell-aware
tokenization;
for
each
bare
grep,
egrep,
or
fgrep
segment
that
is
not
path-qualified
or
preceded
by
command,
return
permissionDecision:"deny"
when
the
segment
contains
at
least
two
ranged
quantifiers
{n,m}
or
{n,}
and
an
upper
bound
is
at
least
10.
Route
the
retry
to
Claude’s
built-in
Grep
tool
or
command
grep.
Do
not
rely
on
an
AGENTS.md
warning
alone.
Acceptance
check:
feed
the
hook
synthetic
PreToolUse
JSON
whose
command
is
grep
-E
'[^.]{0,16}x[^.]{0,16}'
/dev/null.
Pass
only
if
it
returns
a
deny
decision
without
starting
grep.
Repeat
with
command
grep,
one
bounded
repeat,
a
literal
recursive
search,
malformed
JSON,
and
a
non-Bash
payload;
all
must
pass
through.
Then
start
a
fresh
Claude
session
and
request
the
hazardous
bare
command.
The
tool
trace
must
show
the
hook
denial
and
no
ugrep
child.
Caveat: Anthropic has not confirmed the open reports, and this run did not execute the resource-exhaustion reproduction. The narrow gate covers the measured bounded-repeat family, not every pathological regex or shell construction. Keep a process-level memory ceiling for unattended workers; after Anthropic ships and you verify a bundled ugrep with the upstream cap, retire the syntax guard only after the canary fails closed.