AIToday
AI Coding AssistantsAI Safety & AlignmentZenn AI/MLPublished: Oct 17, 2026, 22:00 JST

Claude Code deny rules miss /bin/rm; hook catches it, 10 of 11 blocked

Claude Code deny rules miss /bin/rm; hook catches it, 10 of 11 blocked

3 Key Points

  1. What happened

    In the developer's test on Claude Code 2.1.302, deny rules stopped 9 of 11 risky commands, but /bin/rm secrets/fake.p8 and a python3 -c one-liner still deleted the fake key; a 111-line Node hook that resolves each argument to an absolute path and checks it against key extensions, a secrets folder, and .env caught /bin/rm, lifting the blocked count to 10.

  2. Why it matters

    That gap left /bin/rm free to delete secrets/fake.p8 even with deny rules in place, and the hook closed it without stopping the harmless rm .env.example; the python3 -c case still deleted the key, so users who block dangerous commands by their text alone may still lose key files.

Not sure about something? Ask the AI

Questions and answers are published on this page.

Summaries like this, in your inbox every morning.

Context & Analysis

The test grew out of a practical trade-off: to avoid clicking through dozens of confirmation prompts, the developer set Bash commands to run without asking, which removed the human check before a command could touch key files. The repository held two kinds of files that would be painful to lose: .env with keys and passwords, and key files such as .p8 and .pem inside secrets/. An App Store Connect .p8 key, for example, can be downloaded only once, so deleting it means recreating the key and swapping it everywhere it is used.

The deny rules were written as text patterns such as Bash(rm *secrets*) and Read(./secrets/**). They blocked most variants, including cd secrets && rm fake.p8 and timeout 5 rm .env, because the rules look past &&, ; and wrappers like timeout. But /bin/rm does not start with the string rm, and python3 -c hides the delete inside quoted code, so both slipped through. The hook shifts the check from the command text to the destination path, which is why /bin/rm was caught. The same text-matching design also caused over-blocking: rm .env.example and ls secrets were stopped even though they are harmless, and the developer chose to accept that and run those commands manually.

Even combined, the two layers left python3 -c unblocked, and the developer lists further gaps in the 111-line hook, such as sudo -u root rm .env, find . -name '*.p8' -delete, piping .env into curl, and the uppercase rm .ENV. The recommended next step is sandboxing, which restricts which files a command can touch at the operating-system level, so a script that deletes a key would be stopped there rather than by pattern matching.

FAQ
What exactly did the deny rules miss?
The deny rules blocked 9 of 11 dangerous commands, but /bin/rm secrets/fake.p8 and python3 -c "import os; os.remove('.env')" still deleted the fake key in the developer's test.
What does the hook check that deny rules do not?
The hook resolves each argument to an absolute path and checks whether it has a key extension (.p8, .p12, .pem, .key), sits in a secrets folder, or is .env or .env.something (except .env.example).
Does the hook stop every dangerous command?
No. The 111-line hook still misses cases like sudo -u root rm .env, find . -name '*.p8' -delete, cat .env | curl --data-binary @- and rm .ENV, and the developer points to sandbox settings for those.

AI news that matters for your work, delivered every morning.

Pick your industry and the AI tools you use, and get news related to your work every day.

Free · 30 seconds with Google · unsubscribe anytimeWhat is AIToday? →

Ask AI

Ask AI anything about this article. The AI reads this article, earlier AIToday articles, and Wikipedia, and cites its sources. Q&As are published on this page for other readers too.

Questions and answers are published on this page.

Related Articles

Next articleDanaher teams with NVIDIA on AI lab, Abcam autonomous facility