セキュリティ対策
npmのサプライチェーンワーム:インストール時に認証情報が盗まれる仕組みと対策
2026年8月のChainDropは、4時間弱で444パッケージ・2,212バージョンを汚染し、正規の署名(provenance)付きで配布されました。インストール時のフックでnpm・GitHub・クラウド・CIの認証情報を回収し、盗んだトークンでプライベートリポジトリを公開リポジトリとしてコピーします。この一連の流れと、実際に効く防御(インストール時のスクリプト無効化・新しい版の採用を数日待つ・トークンの寿命と範囲・感染疑い時の正しい順序)を手順で解説します。
対象:npm / pnpm を使って開発している人、GitHub にコードを置いている人、CIで自動デプロイしている人。本記事は公開情報(研究機関・ベンダーの分析)にもとづく解説で、攻撃の再現手順や検体そのものは扱いません。
何が起きたのか(ChainDrop / 2026年8月)
2026年8月4日
広く使われるキャッシュ系パッケージのメンテナのGitHubアカウントが侵害される。攻撃者は既存のリリース用GitHub Actionsワークフローを起動して、汚染版をnpmへ公開。4時間弱の間に
444パッケージ・2,212バージョンが汚染。合算で週5億回超ダウンロードされる規模のパッケージ群が含まれた。インストールされると
インストール時フックが動き、npm・GitHub・クラウド(AWS/GCP/Azure)・SSH鍵・Kubernetes・CI/CDの認証情報を回収。CIランナーのメモリから短命のOIDCトークンまで拾う挙動が報告されている。そして
盗んだ認証情報で被害者が公開権限を持つパッケージを次々と汚染して再公開(=ワームとして自己増殖)。回収した秘密は攻撃者が作った公開GitHubリポジトリへ持ち出される。
この系統の主な被害:プライベートリポジトリが公開される
Shai-Hulud系のワームは、盗んだGitHubトークンを使って被害者のプライベートリポジトリを公開リポジトリとしてコピーします(末尾に -migration を付けた名前が報告されています)。GitHubが破られたわけではありません。あなたの端末やCIから盗まれたトークンが、あなたの権限で正規の操作として実行するのです。だから「GitHub側の対策待ち」では守れません。
なぜ止められなかったのか
依存を追加 / CIでインストール
↓ preinstall / postinstall が自動実行
端末・CIランナー上で任意コード実行
↓ npm / GitHub / クラウド / SSH / CIの秘密を回収
盗んだトークンで正規の操作
privateリポジトリを公開コピー/パッケージを再公開して増殖
効かなかったもの
- 署名・provenance:メンテナ権限で正規に発行されたため、検証を通過した
- 「有名なパッケージだから安全」:汚染されたのは広く使われる大手のパッケージだった
- バージョン固定だけ:新しく入れ直す・依存が更新される場面で結局取り込む
- GitHub側の対策待ち:使われたのは正規のトークンと正規のAPI
効くもの
- インストール時スクリプトの既定無効化:実行そのものが起きない
- 新しい版の採用を数日待つ(cooldown):最も危険な「公開〜取り下げ」の期間を避ける
- トークンの短命化と範囲限定:盗まれても使える範囲と時間が小さい
- CIの外向き通信の制限:持ち出しの経路を塞ぐ
今日やる5手順
自分のロックファイルを検索する
汚染が報告されたバージョンが入っていないか、まずロックファイルを直接検索します(例:keyv@6.0.0 / flat-cache@6.1.24 / file-entry-cache@11.1.6)。該当が無ければひとまず安心、ですが手順2以降は今後の同様の攻撃に備える話なので、続けてください。
インストール時スクリプトを既定で止める
CIの npm ci を npm ci --ignore-scripts にする。pnpm なら .npmrc に ignore-scripts=true を置き、本当にビルドが必要な依存だけを onlyBuiltDependencies のように明示的に許可する。これが今回の攻撃の実行段階そのものを止める、最も効く対策です。
新しいバージョンは、公開から数日待ってから採用する
公開直後の版を即座に取り込まない(3〜7日の cooldown)。今回のように公開から取り下げまで数時間〜数日というケースでは、数日待つだけで回避できます。更新の自動PRを使っている場合は、その待ち時間を設定に入れる。
2026-09-05 追記:これは「気をつける」で運用する必要がなくなりました。Node.js公式のセキュリティ指針は、供給網攻撃の緩和策として --min-release-age(npm v11.10.0以降)で依存のクールダウンを設定し、公開されたばかりのパッケージをインストールしないようにすることを挙げています。規律ではなく設定にできるなら、設定にしてください。人の記憶に頼る手順は、忙しい日に抜け落ちます。
トークンを棚卸しして、寿命と範囲を絞る
GitHubのPersonal Access Tokenはclassicをやめてfine-grainedへ、期限は短く、対象リポジトリは必要なものだけに。npmの publish 用トークンはCIに置きっぱなしにしない。鍵と秘密の扱いは .envとAPIキーの基礎 と SSH鍵の最小権限 にまとめています。盗まれる前提で、盗まれても効かない状態を作るのが目的です。
自分のGitHubアカウントを点検する
身に覚えのない公開リポジトリが増えていないか(-migration が付いたもの、見覚えのない説明文のもの)。あわせて、追加された覚えのないGitHub Actionsワークフロー、.vscode/tasks.json や .claude/ に置かれた実行系の設定ファイル、見覚えのないAPIキーとSSH鍵。依存側の既知脆弱性の機械監視は osv-scannerの導入と使い方 をどうぞ。
感染が疑われるときは「順序」を間違えない
研究者が指摘している重要な点があります。端末に残った常駐(トークン監視の類)を先に取り除いてから、トークンを失効させること。順序を逆にすると、失効を検知した常駐側が次の動きを起こし得ます。おおまかな流れは次のとおりです。
1. ネットワークから切り離す
2. 常駐と不審ファイルを除去する
3. npm → GitHub → クラウド → SSH → k8s の順で失効・再発行する
4. node_modules とキャッシュを破棄して入れ直す
5. 公開リポジトリとパッケージの公開履歴を点検する
ログが無い場合の答えは「無かった」ではなく「分からない」です。その場合は侵害された前提で進めてください。
当サイトの視点:署名は出所を保証するもので、安全を保証するものではない
サプライチェーン対策として署名や provenance の導入が推奨されてきましたが、今回はその正規の仕組みを通って汚染版が配られました。署名が保証するのは「誰が出したか」であって、「中身が安全か」ではないので、これは起こり得ることです。侵害されたアカウントから出た正規署名は、正規のまま危険。だから当サイトは、署名を「入れれば安心なもの」ではなく「事故のあとで影響範囲を特定するための道具」として位置づけています。予防の中心はあくまで、インストール時に他人のコードを走らせないことと、秘密をその場に置かないことの2点です。
出典(公開記録)
- Unit 42(Palo Alto Networks)— ChainDrop: Inside a Self-Propagating npm Worm(伝播の仕組み・回収される認証情報・指標)
- StepSecurity — ChainDrop npm Worm(検知指標と復旧手順・失効の順序)
- Elastic Security Labs — CHAINDROP worm hits 400+ npm packages
- SecurityWeek — Over 400 NPM Packages Infected in ChainDrop Supply Chain Attack(規模と経緯)
- Wiz — Shai-Hulud npm Supply Chain Attack(プライベートリポジトリの公開コピーという手口)
- Node.js「Security Best Practices」 — nodejs.org(供給網攻撃の攻撃経路と緩和策。
--ignore-scripts・ロックファイル・npm ci・--min-release-ageによるクールダウン。2026-09-05に確認)
次に読む
- 2026年の実例:TanStack・Nx Console・GitHubの連鎖で開発者が確認すること
- 実務:osv-scannerで依存のCVEを機械監視する / gitleaksでコミット前に秘密を止める
- 基礎:.envとAPIキーは何が危ないのか / SSH鍵の最小権限
- 比較:自前GitサーバーとGitHub、どちらが安全か
- 依存経由の欠陥:プロトタイプ汚染(Node.js)(自分が書いていなくても依存が持ち込む型)
- 用語:マルウェアとは
- 傾向:2026年の情報漏えいは「脆弱性」より「正規の認証情報」で起きている(盗まれたトークンが正規の操作をする、という同じ構図)
よくある質問
Qなぜ npm install しただけで認証情報が盗まれるのですか?
多くのパッケージは、インストール時に自動実行されるスクリプト(preinstall / postinstall)を持てるためです。つまり依存を1つ追加することは、そのコードを自分のユーザー権限で実行させることと同じです。ChainDropはこの仕組みを使い、npm・GitHub・クラウド・SSH・CI/CDの認証情報を回収していました。
Qプライベートリポジトリが公開されるとはどういうことですか?
この系統のワーム(Shai-Hulud系)は、盗んだGitHubトークンを使って、被害者のプライベートリポジトリを公開リポジトリとしてコピーします。名前の末尾に -migration を付けたものが報告されています。つまり『GitHubが破られた』のではなく、あなたの端末やCIから盗まれたトークンが、あなたの権限でそれを行います。
Q署名やprovenanceがあるパッケージなら安全ではないですか?
今回はそこが突破されました。攻撃者はメンテナの権限で既存のリリース用ワークフローを起動し、正規の署名(provenance)が付いた状態で汚染版を公開しています。署名は『誰が出したか』を保証するもので、『中身が安全か』は保証しません。侵害されたアカウントから出た正規署名は、正規のまま危険です。
Q今日できるいちばん効く対策は?
インストール時スクリプトを既定で無効化すること(`npm ci --ignore-scripts` / pnpm の `ignore-scripts=true`)と、新しい版をすぐに採用せず、公開から数日待つこと(cooldown)の2つです。前者は攻撃の実行そのものを止め、後者は『公開から取り下げまでの数時間〜数日』という最も危険な期間を避けます。