npm で大規模サプライチェーン攻撃発生:私が実際に行った影響調査と復旧手順まとめ
2025年11月、npm レジストリの正規パッケージに悪性コードが混入するという重大インシデントが発生しました。
これは 「正規メンテナーアカウントが侵害され、正規パッケージの最新版にマルウェアが混入する」 という非常に危険な攻撃手法で、世界的に大きな影響を与えました。
本記事では、
- 今回の攻撃手法のポイント
- 私のプロジェクトで影響が想定されたパッケージ
- 実際に行った安全対策
- CI/CD(GitHub Actions)の改善ポイント
- 再発防止のための運用方針
を整理して紹介します。
同じように npm パッケージを利用している開発者の参考になれば幸いです。
📌 今回の npm 攻撃の概要
今回のインシデントは、一般的なnpm installの仕組みを悪用した巧妙な攻撃でした。
▶ 攻撃の流れ(概要)
- 正規パッケージのメンテナーアカウントが侵害される
- 正規パッケージの「新バージョン」に悪意ある preinstall スクリプトが混入
npm install時に preinstall が自動実行- マルウェアが各種認証情報を窃取し、攻撃者のリポジトリに送信
盗まれる可能性があった情報には、以下が含まれます。
- GitHub Personal Access Token (PAT)
- npm token
- クラウドサービス(AWS, GCP, Azureなど)の認証情報
- CI/CD のシークレット
- 環境変数全般
つまり 「たった一度の npm install」が致命的な被害につながる という危険性がありました。
📌 私のプロジェクトで問題となった依存関係
私のリポジトリでは API テスト用途で newman を利用しています。
この newman が依存している postman-request の内部で、以下のパッケージが使われています。
@postman/tunnel-agent
そして、このパッケージのバージョン履歴を見ると、問題の 2025/11/24 に以下のような「怪しい最新版」が公開されていました。
(0.6.5 以上)
$ npm view @postman/tunnel-agent time
{
created: '2019-05-08T09:00:14.942Z',
modified: '2025-11-25T08:04:45.566Z',
'0.6.2': '2019-05-08T09:00:15.240Z',
'0.6.3': '2019-11-07T05:52:12.422Z',
'0.6.4': '2024-07-18T05:52:19.650Z',
'0.6.5': '2025-11-24T05:04:37.688Z',
'0.6.6': '2025-11-24T05:10:19.400Z',
'0.6.7': '2025-11-24T05:13:17.472Z'
}幸い、私の package-lock.json には 安全な 0.6.4 がロックされていましたが、もし何か変更して npm install を実行していたら 0.6.5 以上の悪性バージョンがインストールされてしまう恐れがありました。
📌 実施した対応内容
1. GitHub Actions を npm install → npm ci に変更
npm ci の特徴:
package-lock.jsonを 完全に忠実に再現- lock ファイルと矛盾があればエラー
- 不要なバージョンへの自動更新が絶対に発生しない
CI/CD では確実に 0.6.4 のままになるため、攻撃リスクが大幅に下がります。
- name: Install packages
run: npm ci2. package.json に overrides を追加して強制固定
npm v8+ の overrides を使い、プロジェクト全体で @postman/tunnel-agent を 0.6.4 に強制固定 しました。
"overrides": {
"@postman/tunnel-agent": "0.6.4"
}これにより、
- 間接依存(transitive dependency)でも 0.6.4 に固定
- 誤って npm install を実行しても 0.6.5+ に上がらない
という二重の安全性を確保できます。
3. 過去の GitHub Actions を確認し、危険な更新がなかったことを確認
actions/cache を使っていたため、
- 11/24 や 11/25 にキャッシュが作り直されていないこと
- 最新キャッシュが問題発生前のものだったこと
をログから確認し、過去に悪性バージョンを踏んでいないことを確認しました。
4. ローカルで npm install を行わない運用に変更
ローカル環境は必要最低限であったり一時的(短時間)ではあるものの、GitHub PAT やクラウドクレデンシャルなどを保持しているため、万が一でも悪性パッケージを踏むと影響が大きいです。
そのため、
- ローカルは基本 npm ci
- 依存更新が必要なときのみ、隔離環境で npm install
- 普段の開発では npm install を使わない
こうした運用方針で今回の対応は行いました。
📌 まとめ:今回の npm インシデントから学んだこと
今回のサプライチェーン攻撃を通して、個人的に強く感じたポイントは次の3つです。
- 依存の更新は“リスク”でもある
最新版を取るだけで汚染物が入る可能性がある。ロックファイルの運用や依存管理は本当に重要。 - npm install を軽く使わない
ローカルで安易に install すると、CI より先に“汚染バージョンが混入”するリスクがある。 - CI とローカル開発の再点検が必要
npm ci の利用、overrides の活用など、日常的な運用を見直すきっかけになった。
🔐 最後に:同じ状況に遭遇した場合の行動指針
もし今回と同じようなサプライチェーン攻撃に遭遇した場合、私なら次の2つを最優先で行います。
1. 影響バージョンをインストールしていないか確認する
CI/ローカル両方の環境で、汚染パッケージが混入していないかを確認する。
2. “入れてしまった可能性” があるなら、秘密情報を必ずローテーションする
仮に実行されていなかったとしても、汚染パッケージにトークンや鍵を送信するコードが仕込まれていた可能性 があるためです。
ローテーションすべき情報は以下の通り。
- GitHub の Personal Access Token (PAT)
- CI/CD の環境変数(API キー、アクセストークン)
- クラウドプロバイダのアクセスキー(AWS IAM 等)
- 特殊な CLI の auth トークン(Firebase、Vercel、Netlify など)
特に CI 環境に汚染バージョンが入り込むと、ビルド時の環境変数が一括で盗まれる可能性がある ため、早めのローテーションがもっとも現実的な防御になります。
npm だけではなく、サプライチェーン攻撃は誰でも遭遇しうるもの。
今回の経験が、同じ状況に直面した方の役に立てば幸いです。
