【2026年版】npmのサプライチェーン攻撃と対策|Shai-Hulud・ChainDropの手口と、使う側・公開する側がやること
はじめに
npm(Node.js のパッケージの置き場)で、パッケージを乗っ取って悪いコードを混ぜる攻撃が続いています。2025 年 9 月の「Shai-Hulud」から、2026 年も 5 月、6 月と続き、8 月には「ChainDrop」で 400 を超えるパッケージが乗っ取られました。
こうした攻撃は、自分のコードに問題がなくても、使っているライブラリの、さらにその先のライブラリから入り込みます。この記事では、最近の手口と、パッケージを使う側・公開する側の対策をまとめました。
2026 年 8 月の ChainDrop で何が起きたか
Elastic と Microsoft の分析によると、流れは次のとおりです。
- よく使われるライブラリ「keyv」のメンテナーのアカウントが乗っ取られ、悪いコードを混ぜた版が公開された
- その版をインストールしただけで、package.json の preinstall スクリプトが動き、悪いプログラムを実行する
- パソコンや CI の中から、npm・GitHub のトークン、クラウドの鍵、SSH の鍵、AI ツールの API キーなどを集めて送る
- 盗んだ npm のトークンが公開の権限を持ち、2 段階認証を回避できるものなら、そのメンテナーが公開できるすべてのパッケージに悪いコードを入れて、次の版を出す(ワームのように広がる)
- 盗んだ GitHub のトークンで、リポジトリのエディタや AI ツールの設定ファイル(
.vscode/tasks.json・.claude/settings.json)にフックを書き込み、リポジトリを開いたときにも動くようにする
影響を受けたパッケージは 400 を超え、合わせると月に 13 億回以上ダウンロードされる規模でした。また、GitHub Actions からの「trusted publishing」で公開された悪い版もあり、正しい出どころの証明(provenance)が付いていました。出どころの証明は「どこから公開されたか」を示すもので、「公開した環境が安全だったか」までは保証しません。
使う側の対策
1. lockfile を使い、CI では npm ci
package-lock.json をリポジトリに入れて、CI や本番では npm ci を使います。lockfile に書かれた版だけを入れるので、知らないうちに新しい(悪い)版が入るのを防げます。
# lockfile のとおりに入れる(lockfile と package.json が食い違うとエラーで止まる)
npm ci2. 新しい版をすぐ取り込まない
乗っ取られた版は、多くの場合数時間〜数日で見つかって消されます。公開されてから数日寝かせてから取り込むだけで、多くの被害を避けられます。
- pnpm:
minimumReleaseAgeで、公開されてから指定の時間がたつまで入れない - Renovate:
minimumReleaseAgeで、更新の提案を遅らせる - Dependabot:
cooldownで、新しい版の提案を遅らせる
# 公開から 3 日(4320 分)たっていない版は入れない
minimumReleaseAge: 43203. インストールスクリプトを止める
今回のように、攻撃の多くは preinstall・postinstall などのスクリプトで動きます。ビルドが必要なパッケージ以外は、スクリプトを動かさない設定にしましょう。
# npm:インストール時のスクリプトを動かさない
npm config set ignore-scripts true
# 必要なパッケージだけ、あとで個別にビルドする
npm rebuild <パッケージ名>- pnpm は 10 から、依存パッケージのスクリプトを既定で動かしません。必要なものだけ
onlyBuiltDependenciesで許可します - Elastic によると、npm 12 以降も preinstall フックを既定で止めるようになっています。npm を新しくしておきましょう
4. 署名と既知の問題を確かめる
# 既知の脆弱性・悪いパッケージの確認
npm audit
# 入れたパッケージの署名と出どころの証明を確かめる
npm audit signatures5. 開発のパソコンと CI に鍵を置きすぎない
.npmrcや環境変数に、長く使える強いトークンを置きっぱなしにしない- CI では、ジョブごとに必要な権限だけを持つ短い期限のトークンを使う(GitHub Actions の OIDC など)
- クラウドの鍵は、パソコンに保存せず、一時的な認証情報を使う
公開する側(メンテナー)の対策
- npm のアカウントに2 段階認証を設定する。できればセキュリティキーやパスキーで(コードを入力する方式は、偽サイトでだまし取られる)
- 2 段階認証を回避できるトークンを作らない。今回のワームは、こうしたトークンで広がった
- CI から公開するなら、長く使えるトークンの代わりに trusted publishing(OIDC) を使う
- ただし trusted publishing でも、公開するワークフローそのものが乗っ取られると悪い版が出せる。公開のワークフローは手動の承認(GitHub の Environments の保護)を通す
- GitHub Actions のアクションはコミットの SHA で固定し、
pull_request_targetなどの危ないトリガーで公開しない
npm のアカウントや GitHub の 2 段階認証の選び方は、【2026年版】2段階認証の種類と強さを比較にまとめています。
乗っ取られた版を入れてしまったら
- 影響を受けたパッケージの一覧(Elastic・Microsoft・各セキュリティ会社が公開)と、lockfile を照らし合わせる
- 入れてしまったなら、そのパソコンや CI にあったすべての鍵を取り消して作り直す(npm・GitHub のトークン、クラウド、SSH、AI ツールの API キーなど)
- GitHub のリポジトリに、覚えのないコミット(設定ファイルの変更など)や、
.vscode/tasks.json・.claude/settings.jsonへの書き込みがないか確かめる - 自分がメンテナーなら、自分のパッケージに覚えのない版が出ていないか確かめ、あれば npm に報告して取り下げる
まとめ
- npm では、乗っ取ったパッケージから鍵を盗み、ほかのパッケージへ広がるワーム型の攻撃が続いている(2026 年 8 月の ChainDrop は 400 超)
- 使う側は lockfile と npm ci、新しい版を数日寝かせる、インストールスクリプトを止める
- 公開する側は 強い 2 段階認証、2 段階認証を回避するトークンを作らない、公開のワークフローを守る
- 出どころの証明(provenance)は、「安全な版」の証明ではない
Node.js 本体のバージョンアップは【2026年版】古いNode.jsからLTS(24・26)へのバージョンアップ手順をどうぞ。
参考
セキュリティ会社の分析(2026 年 10 月 31 日時点)をもとにまとめています。
Shai-Hulud strikes again: CHAINDROP worm hits 400+ npm packages - Elastic Security Labs
ChainDrop supply chain compromise: Anatomy of a self-propagating worm - Microsoft Security Blog
Ongoing npm Supply Chain Attack Affecting Keyv and Related Packages - CSA Singapore



