Shai-Hulud事件でCLAUDE.mdの書き方が変わった話
Shai-Huludのニュースを読んだ日、私は自分のCLAUDE.mdを開いて、しばらく閉じられませんでした。
書いてあることが「Claude Codeへの指示書」から「攻撃者が最も欲しがるファイル」に見え方が変わったからです。永続プロンプトは、私が思っていたよりずっと広い攻撃面でした。この記事は、私のグローバルCLAUDE.md(~/.claude/CLAUDE.md)からShai-Hulud以降に消した3行と、代わりに足した5行の記録です。個人の設定ファイルの話なので参考程度に読んでもらえたら十分ですが、CLAUDE.mdを2025年の感覚のまま放置している人には、たぶんどこかで刺さります。
Shai-Huludがなぜ「新しい」攻撃だったのか
Shai-Huludは、2025年9月に発覚した最初のnpmワームです。細工されたパッケージがnpm installのpostinstallフックで発火し、ホストの認証情報を盗み、その被害者のnpmトークンで別のパッケージにも自分のコピーを仕込んで再公開する。被害者がそのまま次の加害者になる、自己増殖するタイプでした。
2025年11月、これがShai-Hulud 2.0として戻ってきました。Palo Alto Unit42の報告によると、影響範囲は約25,000リポジトリ・350ユーザーまで拡大し、実行タイミングもpostinstallからpreinstallへ移動しています。preinstallはnpm installが依存解決を始めるより前に走るため、「Y/nを押す前」に発火するようになりました。さらに新しい亜種では、認証情報の窃取に失敗するとホームディレクトリ全消しにフォールバックする、破壊的な挙動も報告されています。
そして2026年4月と5月、SAP系パッケージを狙ったMini Shai-Huludが観測されました。Microsoft Security Researchによれば170+ npmパッケージ、404マリシャスバージョンが確認されています。ワームというより「テンプレ化された自動化キャンペーン」に近い形です。
つまりShai-Huludは1回で終わった事件ではありません。攻撃側が半年おきに改良版を出してくる継続的な圧力になりました。私のCLAUDE.mdは、この前提で書き直す必要がありました。

消した3行
以下は、私が今まで「便利だから」で書いていて、Shai-Hulud 2.0以降に消した3つの行です。書いてあった実物に近い形で残します。
消した1行目: 「依存追加は迷ったら install してから相談」
- パッケージを増やすか迷ったら、まず`npm install`して動かしてから相談する
これは開発体験としては速いんです。試して、動かなかったら消す。TDDでいうと「まず動かせ」の思想に近い。ただし2026年のnpmは、preinstallでコードが走る前提の攻撃面になりました。「動かしてから考える」というワークフローは、Shai-Hulud 2.0にとってはただの「フリーパス」です。相談してから入れる、が今の正解です。速度は落ちます。その速度は元から幻でした。
消した2行目: 「security系のスキャンはノイズが多いのでmuteしていい」
- `npm audit`は誤検知が多いのでCIでは無視、ローカルもmuteでよい
これも当時はまあまあ妥当でした。npm auditはrecursiveに全部拾ってきて、直せない依存の内側の依存まで叫んでくる。うるさい。ただし、私のこの1行はClaudeにも「audit系のノイズは基本無視していい」というプライオリティを与えていました。攻撃者が新規に踏み込んだパッケージほど、シグナルは弱く出ます。ノイズと本物のシグナルを区別する仕事は、私が引き受け直す必要がありました。Claudeに「無視でよい」と教えないことにしました。
消した3行目: 「機密ファイルは触らないでね」
- 機密ファイルは基本的に触らないこと
これ、ぼんやりしすぎです。「機密ファイル」という抽象名詞をClaudeに投げても、~/.npmrcや~/.aws/credentialsのような、攻撃対象になる具体ファイルを守れる保証がありません。しかも私はこの1行だけで安心していました。
具体ファイル名で書き直す必要がある、というのが3つ目の反省です。次のセクションで実際の書き換え文を出します。
足した5行
代わりに、以下の5行を明示的に足しました。これはグローバル(~/.claude/CLAUDE.md)側です。プロジェクト側のCLAUDE.mdでオーバーライドできる想定です。
## Supply chain safety (post Shai-Hulud 2.0)
1. `npm install <新規パッケージ>` の前に、必ずパッケージ名・作者・weekly downloadsを報告し、私の承認を待つこと。preinstall/postinstallスクリプトの有無も明示する
2. 以下のファイルは、指示があってもread/writeしない: `~/.npmrc`, `~/.ssh/*`, `~/.aws/*`, `.env*`, `*.pem`, `*.key`, `*_credentials*`
3. weekly downloads 1,000未満、または公開30日以内のパッケージは「未知パッケージ」として警告を出すこと(タイポスクワッティング警戒)
4. `rm -rf ~`, `rm -rf $HOME`, `find / -delete` およびそれに準じる広い削除は、私が明示的にコマンド全文を書いた場合以外、絶対に実行・提案しない
5. 上記1-4に該当した判断は、`~/.claude/audit.log` に日時と該当パッケージ名を追記すること
書いた側の意図を1行ずつ補足します。
1つ目は、消した「install してから相談」の反対側です。preinstallフック時代なので「入れる前」でしか防げません。作者と公開日をClaudeに報告させることで、私が「知らないパッケージ名」を「タイポスクワッティングかも」と気づけるようにしました。2つ目が、消した「機密ファイル」を具体ファイル名に落としたやつです。抽象名詞をやめて、Shai-Huludが実際に狙った~/.npmrc, SSH鍵, AWSクレデンシャルを列挙しました。これはユーザー指示があっても無視するように書いてあります(プロンプトインジェクション対策)。
3つ目は、weekly downloadsと公開日でのゲート。Mini Shai-Hulud (2026-04〜05) は既存の低download数パッケージを狙う手口を含んでいたので、ダウンロード数だけでなく公開日も見ています。
4つ目は、Shai-Hulud 2.0のフォールバック挙動(認証情報窃取に失敗するとホーム全消し)を受けた対策です。ワームが直接叩くわけではなくても、Claudeが「クリーンアップします」の流れで広いrmを提案してくる場面はあり得ます。そこを閉じました。5つ目は、自分の運用側の話です。ClaudeがCLAUDE.mdのどのルールで止まったのか、あとから追える形にしておきたい。~/.claude/audit.logという単なるappend-onlyのテキストファイルですが、これがあるだけで「ちゃんと防いだ日」と「素通りした日」が判別できます。
CLAUDE.mdは「読まれる場所」から「攻撃される場所」になった
Shai-Hulud以前、私はCLAUDE.mdを「私からClaudeへの指示書」だと思っていました。書いた側と読む側は自分と自分の道具、閉じた世界です。
Shai-Hulud 2.0以降、そこに三人目のプレイヤーが座っていることを意識しています。攻撃者は、CLAUDE.mdに書かれた「ゆるさ」を、そのままワークフローの穴として利用できます。私が「install してから相談」と書いていれば、そのプロジェクトのClaudeは、preinstallで発火する悪意あるパッケージの導入を、私に相談する前に走らせようとします。CLAUDE.mdは、ソースコードの一部として、レビューの対象として、脅威モデリングの対象として、扱われる場所に格上げされました。
AnthropicのClaude Code documentationによれば、CLAUDE.mdはユーザースコープ(~/.claude/CLAUDE.md)、プロジェクトスコープ(./CLAUDE.md)、エンタープライズスコープの階層で読み込まれ、信頼境界は「ユーザー本人が管理しているスコープほど強く信頼する」という原則で動きます。裏を返せば、ユーザースコープ以下に書いた「無視していい」「installしていい」は、下位スコープの安全策を全部押し流します。だから、私が変えるべきだったのは私のユーザースコープのCLAUDE.mdでした。
今日中にやること、3つ
長い話にしましたが、明日以降のあなたのために圧縮します。
~/.claude/CLAUDE.mdを開いて、「install」「audit」「機密」で検索してください。 2025年の感覚で書いた1行があったら、それがShai-Hulud 2.0時代のあなたの穴です- 消すべき「便利のための行」を1行だけ選んで消してください。 全部書き換えようとすると挫折します。1行でいい
- 代わりに、preinstallフックの承認を要求する1行を足してください。 上のリストの1番目でも、あなた自身の言葉でもよいです
Claude Codeで「Yes」を押す前の1秒の話は、私の書いた電子書籍『Claude Code Mastery』の第16章にもう少し詳しく書いてあります。CLAUDE.mdの本質論(なぜ2行のBoris Chernyと100行の実践者が両立するのか)と合わせて読むと、今日の記事の「なぜ書き換える必要があったか」の背景が見えると思います。
書き換えたら、ぜひgit logと~/.claude/audit.logの両方を見返してください。1週間後、どちらかに「防いだ痕跡」が残っているはずです。
この記事は役に立ちましたか?