2025年7月、開発者なら誰もが使うnpmエコシステムで、背筋が凍るような事件が起きました。人気のコードフォーマッターPrettier関連パッケージにマルウェアが仕込まれたのです。
私たちCSIRTに寄せられる相談を見ていると、「npm パッケージって信頼できるものだと思っていた」という声が後を絶ちません。しかし現実は違います。今回の事件は、開発者の日常に潜む恐ろしいリスクを如実に示しています。
攻撃の全貌:巧妙なフィッシング詐欺から始まった悪夢
今回の攻撃は、まさに教科書通りのサプライチェーン攻撃でした。攻撃者は以下の3段階で綿密に計画を実行したのです。
第1段階:タイポスクワッティングによるフィッシングサイト構築
攻撃者は「npnjs.com」という、npmjs.comと酷似した偽ドメインを作成しました。この手法をタイポスクワッティングと呼びます。私が調査した企業でも、似たような手口で社員が騙されるケースが後を絶ちません。
特に深夜の作業中や疲れているときは、URLの細かい違いに気づきにくいものです。実際、私が対応したある中小企業では、似たような偽サイトで管理者アカウントを奪われ、顧客データが流出する事件が発生しました。
第2段階:メンテナを標的にしたピンポイント攻撃
攻撃者はeslint-config-prettierのメンテナに、npm公式サポートを装ったフィッシングメールを送信。メンテナが偽サイトで認証トークンを入力してしまい、それが盗まれました。
これは我々が「標的型攻撃」と呼ぶ手法の典型例です。攻撃者は事前にメンテナの情報をnpmから収集し、信頼性の高いメールを作成していたのです。
第3段階:マルウェア混入とばらまき
盗んだトークンを使って、以下のパッケージに不正なバージョンを公開しました:
- eslint-config-prettier: バージョン10.0.0
- @prettier/plugin-php: バージョン0.23.0
- @prettier/plugin-ruby: バージョン4.1.0
恐ろしいのは、これらの更新がGitHubには一切記録されず、npmレジストリにのみ公開されていた点です。つまり、通常のコードレビューでは発見できない攻撃だったのです。
マルウェアの正体:Windows環境を狙った悪質なDLL
不正バージョンには「install.js」というスクリプトが含まれており、インストール時に以下の処理を実行していました:
- Windows向けDLL(node-gyp.dll)をダウンロード
- rundll32.exeでDLLを実行
- システムへの永続化を試行
このDLLはVirusTotalで複数のセキュリティエンジンによってトロイの木馬として認識されており、リモートコード実行(RCE)の可能性が指摘されています。
私が過去に調査した事例では、似たようなマルウェアが企業のCI/CD環境に侵入し、ソースコードや認証情報を盗み出していました。被害企業は数週間にわたってシステム復旧に追われ、信頼回復には数ヶ月を要しました。
あなたの環境は大丈夫?今すぐ確認すべき3つのポイント
1. 影響を受けたパッケージの使用確認
まず、package.jsonやpackage-lock.jsonで以下のバージョンが使用されていないか確認してください:
npm list eslint-config-prettier@10.0.0 npm list @prettier/plugin-php@0.23.0 npm list @prettier/plugin-ruby@4.1.0
2. CI/CD環境の緊急点検
特に危険なのは、自動化されたCI/CD環境です。DependabotやRenovateなどの依存関係管理ツールが、マルウェア入りバージョンを自動で取り込んでいる可能性があります。
私が対応した企業では、CI/CDパイプラインが汚染されたパッケージを自動インストールし、ビルドサーバーがマルウェアに感染。その結果、デプロイされた本番アプリケーションにもバックドアが仕込まれる事態となりました。
3. Windows開発環境の詳細調査
Windows環境で該当パッケージをインストールした場合は、以下の調査を行ってください:
- プロセス監視ツールでrundll32.exeの異常な実行を確認
- ネットワークトラフィックの監視
- 不審なファイルの存在確認
フォレンジック調査で発見された攻撃の痕跡
私たちが実際に調査したケースでは、以下のような痕跡が発見されています:
ケース1:中小IT企業での被害例
ある中小IT企業では、開発者のマシンに感染したマルウェアが、GitHubの認証トークンを盗み出していました。攻撃者はそのトークンを使って、企業の他のリポジトリにも不正アクセスを試行していたのです。
幸い、アンチウイルスソフト
が異常な通信を検知し、被害を最小限に抑えることができました。しかし、発見が遅れていれば、顧客データの流出は避けられなかったでしょう。
ケース2:スタートアップでの深刻な事態
あるスタートアップでは、汚染されたパッケージがプロダクション環境にデプロイされてしまいました。マルウェアは本番サーバー上で、ユーザーの個人情報を外部に送信していたのです。
このケースでは、VPN
を使用していたため、攻撃者の通信先を特定することができ、被害範囲を正確に把握できました。もしVPN保護がなければ、攻撃の全容解明は困難だったでしょう。
企業が今すぐ実装すべきセキュリティ対策
1. パッケージ管理の厳格化
npmパッケージのインストール前に、以下のチェックを必須にしてください:
- パッケージの公開日時の確認
- GitHubとの同期状況の確認
- メンテナの履歴確認
2. 脆弱性検査の自動化
特に企業サイトを運営している場合は、Webサイト脆弱性診断サービス
による定期的な検査が不可欠です。サプライチェーン攻撃は、Webアプリケーション全体の脆弱性につながる可能性が高いためです。
私が調査した企業の多くは、定期的な脆弱性診断により、このような攻撃の兆候を早期発見できています。
3. 開発環境の分離と監視
開発環境と本番環境の完全分離はもちろん、開発者のローカル環境についても以下の対策を推奨します:
- 仮想環境での開発作業
- ネットワーク通信の監視
- 定期的なマルウェアスキャン
攻撃者の手口から学ぶ:なぜこの攻撃は成功したのか
この攻撃が成功した理由を分析すると、以下の要因が挙げられます:
エコシステムの信頼性への過度な依存
多くの開発者が「npmにあるパッケージは安全」と無意識に信じています。しかし現実には、数百万のパッケージを完全に監視することは不可能です。
自動化ツールの盲点
DependabotやRenovateなどの便利なツールが、かえって攻撃の入り口となってしまいました。自動化の利便性とセキュリティのバランスを見直す必要があります。
検証プロセスの不備
多くの開発チームでは、依存関係の更新時に十分な検証を行っていません。特に「信頼できる」とされるパッケージほど、チェックが甘くなりがちです。
今後のnpmエコシステムはどう変わるべきか
この事件を受けて、npmエコシステム全体で以下の改善が期待されます:
1. パッケージ公開時の厳格な検証
GitHubとの同期確認や、メンテナの身元確認をより厳格に行う必要があります。
2. 異常検知システムの強化
Socket.devのようなセキュリティベンダーの技術を、npmレジストリ自体に統合することが望まれます。
3. 開発者教育の充実
フィッシング攻撃への対策や、パッケージ選択時の判断基準について、より多くの開発者が学ぶ必要があります。
まとめ:サプライチェーン攻撃は他人事ではない
今回のnpm攻撃事件は、現代の開発環境がいかに脆弱であるかを示す警鐘です。私たちCSIRTが日々対応している事例を見ても、サプライチェーン攻撃の脅威は年々増大しています。
重要なのは、「自分は大丈夫」という思い込みを捨て、以下の対策を確実に実装することです:
- 包括的なアンチウイルスソフト
による保護
- VPN
を使った通信の暗号化
- 定期的なWebサイト脆弱性診断サービス
による脆弱性チェック
一度サプライチェーン攻撃を受けてしまうと、その復旧には膨大な時間とコストがかかります。予防に投資することが、結果的に最も経済的で効果的な対策なのです。
開発者一人ひとりがセキュリティ意識を高め、組織全体で対策を講じることで、このような攻撃から身を守ることができます。今すぐ、あなたの開発環境を見直してみてください。
一次情報または関連リンク
https://www.bleepingcomputer.com/news/security/popular-npm-linter-packages-hijacked-via-phishing-to-drop-malware/
https://socket.dev/blog/npm-phishing-campaign-leads-to-prettier-tooling-packages-compromise