Skip to content

BuildNot yet confirmed elsewhere1 publisher2 min readPublished

Claude Code's deny rules missed an env-prefixed rm -rf in every 2.1.288 run

A dev.to tester ran TZ="$HOME" rm -rf build past a Claude Code 2.1.288 Bash(rm *) deny rule in 6 of 6 sandboxed runs. Version 2.1.289 stopped all six, but bash -c 'rm -rf build' still ran in 6 of 6 sandboxed runs on that build.

The Engineer · Build desk

How we use AISend a correction

Illustration accompanying Claude Code's deny rules missed an env-prefixed rm -rf in every 2.1.288 run
Generated illustration
On 2.1.289, the TZ form was stopped, bash -c ran Runs per rm -rf build form on Claude Code 2.1.289, per a dev.to tester; each label gives the setup the tester reports for that form.

On Claude Code 2.1.289, FOO="$(pwd)" rm -rf build ran in 7 of 7 runs where Bash was otherwise allowed or permissions were bypassed; bash -c 'rm -rf build' ran in 6 of 6 sandboxed runs; TZ="$HOME" rm -rf build was stopped in 6 of 6 runs.

On 2.1.289, the TZ form was stopped, bash -c ran
FigureValueNoteClaim
FOO="$(pwd)" rm -rf build, Bash allowed or bypassed7 of 7 runs ran7
bash -c rm -rf, sandboxed6 of 6 runs ran6
TZ="$HOME" rm -rf stopped6 of 6 runs5

What happened

  • The 2.1.289 changelog lists two fixes: a rule missing a command behind an env prefix with an expanded value, and a rule skipped when a bare variable assignment came first.
  • Both bugs need the Bash sandbox on, its auto-allow mode at the default, and a deny or ask rule the user expected to hold.
  • The tester ran 39 headless sessions on 2026-10-05 on macOS under Seatbelt, comparing the installed 2.1.289 build with the 2.1.288 npm package.
  • The permissions page's own table lists bash -c 'rm -rf build/' and /bin/rm -rf build/ as forms that Bash(rm *) does not stop.

Why it matters

  • contradiction The sandboxing page says explicit deny rules are always respected under auto-allow, yet 2.1.288 deleted the folder in all six TZ runs.
  • exposure The permission modes page lists this setup as a common one, so the 2.1.288 gap reached ordinary configurations.
  • decision Teams that put destructive commands in deny need to check which spellings their agents can reach, since a bash -c wrapper passed in 6 of 6 sandboxed runs.

A Bash rule is a text match. The permissions page says it "matches the command text Claude writes, after Claude Code splits compound commands and strips wrappers" [15]. The stripped wrappers are timeout, time, nice, nohup, stdbuf, command, builtin and noglob. env is not on the list [2].

Leading variable assignments get two treatments. For allow rules, Claude Code strips known-safe variables, so Bash(npm test *) matches NODE_ENV=test npm test, and an allow rule will not match past any other variable [3]. TZ sits on the known-safe list that a 2.1.98 changelog entry describes [1]. The dev.to write-up flags that list as relevant to the 2.1.288 bug [1]. The changelog fix is worded around an expanded value, "$HOME", behind the prefix [8].

The bash -c result confirms documented behavior. The 6 of 6 sandboxed runs on 2.1.289 are what the docs table predicts for that form [6].

On the FOO="$(pwd)" case, the 2.1.289 changelog says a rule skipped after a bare variable assignment was fixed [8]. The docs say deny rules match past any leading assignment [13]. The write-up's opening summary describes the seven runs by configuration, Bash "otherwise allowed or permissions were bypassed", and does not say a deny rule was loaded in each one [7]. Together with bash -c, that is 13 of 13 runs executing on 2.1.289, under two different configurations [17].

For the numbers to transfer, a deployment needs the setup the two bugs share, plus the tester's platform and model: macOS under Seatbelt, claude-opus-5-5 [11]. The deletion target was a throwaway build/ folder, recreated before every attempt [12].

In our view, a deny rule is a guard on Claude's usual phrasing, which is how the docs scope it: the rule "covers the invocation Claude usually produces and isn't a security boundary around the program" [15]. A limit that has to hold against rephrasing belongs below the command text, in what the sandbox and the filesystem allow.

What to watch

  • A per-run breakdown of the seven FOO="$(pwd)" runs, showing whether a deny rule was loaded under sandbox auto-allow in each.
  • Whether a later Claude Code changelog entry extends rule matching to bash -c or other shell wrappers, or the docs keep listing it as uncaught.
  • Reruns of the same test on a non-macOS sandbox or another model, to see if the 6 of 6 results hold.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence68
Adoption
Insufficient
Hype gap−10
Incentives
Insufficient
Confidence65
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    A 2.1.98 changelog entry says read-only commands with env-var prefixes did not prompt unless the var is known-safe (LANG, TZ, NO_COLOR, etc.); the write-up says TZ and LANG are on a known-safe list and that this matters to the bug.

    ReportedSupportedSource: Claude Code changelog and dev.to write-up2 sources— create a free account to open themView cited source
  2. [2]

    The wrappers Claude Code strips before matching are timeout, time, nice, nohup and stdbuf, plus the shell builtins command and builtin, and zsh's noglob; env is not on the list.

    ReportedSupportedSource: Claude Code permissions page, as quoted by the dev.to write-up2 sources— create a free account to open themView cited source
  3. [3]

    Claude Code strips a leading assignment of certain known-safe environment variables, so Bash(npm test *) matches NODE_ENV=test npm test; an allow rule won't match past an assignment of any other variable.

    ReportedSupportedSource: Claude Code permissions page, as quoted by the dev.to write-up2 sources— create a free account to open themView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 12, 2026

    Claude Code 2.1.288 ran TZ="$HOME" rm -rf build past sandboxed deny and ask rules 6 of 6 times; 2.1.289 stopped all 6

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

Loading related stories