サプライチェーン攻撃とnpm|タイポスクワッティング・依存パッケージ対策を解説

npmは世界最大のパッケージレジストリであり、200万以上のパッケージが登録されています。その規模の大きさと依存関係の複雑さは、サプライチェーン攻撃の格好の標的となっています。event-stream事件、ua-parser-js事件、node-ipc事件など、npmエコシステムでは深刻なサプライチェーン攻撃が繰り返し発生しています。この記事では、npmエコシステムにおけるサプライチェーン攻撃対策を詳しく解説します。タイポスクワッティング、悪意あるパッケージの検出、依存パッケージのロックファイル管理まで、npm特有のリスクと対策を紹介します。

npmエコシステムのサプライチェーンリスク

npm(Node Package Manager)は、世界最大のパッケージレジストリです。2024年時点で200万以上のパッケージが登録されており、週間ダウンロード数は数十億に達します。JavaScript/Node.jsエコシステムの中核を担うnpmは、同時にサプライチェーン攻撃の主要な標的でもあります。

npmエコシステムには、攻撃者にとって魅力的な特徴があります。

規模の大きさ
200万以上のパッケージが存在し、1つのパッケージを侵害すれば多数のプロジェクトに影響を与えられる。
依存関係の深さ
npmプロジェクトは平均して数百のパッケージに依存している。推移的依存(間接依存)まで含めると、把握が極めて困難。
自動インストール
npm installコマンドで依存パッケージが自動インストールされ、postinstallスクリプトが実行される。意識しないうちに悪意あるコードが実行される可能性。
誰でも公開可能
npmレジストリには誰でもパッケージを公開できる。審査プロセスがなく、悪意あるパッケージが混入しやすい。
特徴 メリット セキュリティリスク
オープンな公開 誰でも貢献できる 悪意あるパッケージが公開される
自動依存解決 開発効率向上 把握困難な依存関係
postinstallスクリプト 柔軟なセットアップ 悪意あるコード実行
豊富なパッケージ 再利用性向上 類似名の悪意あるパッケージ

OSSの安全な利用で解説した一般的なリスクに加え、npmには特有のリスクと対策があります。


タイポスクワッティング攻撃

タイポスクワッティングは、npm特有の攻撃手法の代表例です。人気パッケージに似た名前(タイプミスを誘う名前)の悪意あるパッケージを公開し、開発者のインストールミスを狙います。

タイポスクワッティングとは

開発者が「lodash」をインストールしようとして、誤って「lodahs」や「1odash」と入力してしまうことを狙った攻撃です。攻撃者は、人気パッケージのタイプミス版の名前で悪意あるパッケージを事前に登録しておきます。

攻撃の仕組み
人気パッケージの名前に似た悪意あるパッケージを公開。開発者がタイプミスでインストールすると、悪意あるコードが実行される。
狙われやすいパッケージ
週間ダウンロード数が多いパッケージ(lodash、express、react等)ほど狙われやすい。

パッケージのタイポスクワッティングは、npmに限らずPyPI(Python)、RubyGems(Ruby)、Maven(Java)でも発生しています。

典型的なパターン

タイポスクワッティングで使われる典型的なパターンを理解しておきましょう。

パターン 正規パッケージ 悪意あるパッケージ例
文字の入れ替え lodash lodahs、lod-ash
文字の追加 express expresss、express-js
文字の削除 request requst、reques
ハイフンの有無 cross-env crossenv、cross_env
数字と文字の混同 lodash 1odash(lを1に)
スコープの偽装 @angular/core angular-core(スコープなし)

検出方法

タイポスクワッティングを検出・防止する方法を紹介します。

  1. パッケージ名の慎重な確認:インストール前に公式ドキュメントやnpmjs.comでパッケージ名を確認
  2. npm auditの活用:既知の悪意あるパッケージを検出。定期的に実行
  3. Socketなどのセキュリティサービス:悪意あるパッケージをリアルタイム検出
  4. ロックファイルの活用:一度検証したパッケージを固定し、予期しないパッケージを防止

悪意あるパッケージの手口

タイポスクワッティング以外にも、npmエコシステムには様々な攻撃手口があります。

postinstallスクリプトの悪用

npmパッケージには、インストール時に自動実行されるpostinstallスクリプトを定義できます。この機能が悪用されることがあります。

攻撃の仕組み
package.jsonのscripts.postinstallに悪意あるコマンドを記載。npm installを実行した時点で、開発者の意図に関わらず悪意あるコードが実行される。
典型的な悪用例
環境変数(認証情報、APIキー等)の窃取、暗号通貨マイナーのインストール、バックドアのダウンロード、システム情報の収集と送信。

postinstallスクリプトは正当な用途(ネイティブモジュールのビルド等)もあるため、単純に禁止できない点が問題です。

バックドアの混入

正常な機能に隠されたバックドアが混入されることがあります。

  • 難読化されたコード:Base64エンコードや複雑な文字列操作で悪意あるコードを隠蔽
  • 遅延実行:インストール直後ではなく、一定期間後または特定条件で実行される悪意あるコード
  • 条件付き実行:CI/CD環境でのみ動作、特定のホスト名や環境変数がある場合のみ動作

ua-parser-js事件では、正規パッケージに暗号通貨マイナーとパスワード窃取マルウェアが混入されました。

メンテナー乗っ取り

最も深刻な攻撃手口は、正規パッケージのメンテナー権限を乗っ取ることです。

アカウント乗っ取り
メンテナーのnpmアカウントに不正アクセスし、悪意あるバージョンを公開。フィッシング詐欺パスワードリスト攻撃が使われる。
放棄されたパッケージの乗っ取り
メンテナンスが放棄されたパッケージの権限を、ソーシャルエンジニアリングで取得。「メンテナンスを引き継ぎたい」と申し出て権限を譲渡させる。
event-stream事件
2018年、元メンテナーが疲弊し、見知らぬ人物にメンテナー権限を譲渡。その人物が依存パッケージflatmap-streamに悪意あるコードを混入し、ビットコインウォレットを標的にした。

代表的な事例

npmエコシステムで発生した代表的なサプライチェーン攻撃事例を紹介します。

事例名 発生年 手口 影響
event-stream 2018年 メンテナー乗っ取り、依存パッケージへのバックドア混入 200万回以上ダウンロード、ビットコインウォレット標的
ua-parser-js 2021年 メンテナーアカウント侵害 週間800万DL、マイナー・パスワード窃取
coa/rc 2021年 メンテナーアカウント侵害 数百万DL、マルウェア配布
node-ipc 2022年 メンテナー自身による意図的コード ロシア・ベラルーシIPを標的にファイル上書き
event-stream事件(2018年)
人気パッケージevent-streamのメンテナーが疲弊し、見知らぬ人物に権限を譲渡。新メンテナーは依存パッケージflatmap-streamにバックドアを混入。Copay(ビットコインウォレット)を標的にしていた。200万回以上ダウンロードされた後に発覚。
ua-parser-js事件(2021年10月)
週間800万ダウンロードの人気パッケージ。メンテナーのnpmアカウントが侵害され、悪意あるバージョン(0.7.29、0.8.0、1.0.0)が公開。暗号通貨マイナーとパスワード窃取マルウェアが含まれていた。
node-ipc事件(2022年3月)
メンテナー自身が、ロシア・ベラルーシのIPアドレスを検出した場合にファイルを上書きするコードを意図的に追加。「プロテストウェア」と呼ばれる事例だが、サプライチェーンの信頼を損なうものとして批判を受けた。

これらの事件は、npmエコシステムの「信頼モデル」の脆弱性を浮き彫りにしました。1人のメンテナーの判断ミスや悪意が、数百万のプロジェクトに影響を与える可能性があります。

— 出典:Snyk社「npm Security Report」

npm特有の対策

npmエコシステム特有のリスクに対応するための対策を紹介します。

ロックファイルの活用

package-lock.jsonは、npmの最も基本的なセキュリティ対策です。

package-lock.jsonの役割
依存パッケージの正確なバージョン、取得元URL、整合性チェック用のハッシュ値を記録。ビルドの再現性を保証する。
ロックファイルがない場合のリスク
npm installのたびに「最新」バージョンがインストールされ、悪意あるバージョンがリリースされた直後にインストールされる可能性がある。
  1. package-lock.jsonをリポジトリにコミットする
  2. CI/CD環境では「npm ci」コマンドを使用(ロックファイルに従って厳密にインストール)
  3. 依存関係の更新は計画的に実施し、更新後にテストを実行

npm audit

npm auditは、依存パッケージの既知の脆弱性をスキャンするコマンドです。

基本的な使い方
「npm audit」でスキャン実行。脆弱性の深刻度(critical、high、moderate、low)と影響を受けるパッケージが表示される。
npm audit fix
自動修正を試みるオプション。ただし、メジャーバージョンアップが必要な場合は手動対応が必要。本番環境への適用前にテストを実施すること。
CI/CDへの組み込み
「npm audit --audit-level=high」で高以上の脆弱性がある場合にビルドを失敗させる設定が可能。

スコープパッケージの活用

スコープパッケージ(@org/package形式)を活用することで、依存関係混乱攻撃のリスクを軽減できます。

  • 組織スコープ(@mycompany/internal-lib等)で内部パッケージを公開
  • 公開レジストリと内部レジストリの名前空間を分離
  • プライベートレジストリ(npm Enterprise、Verdaccio、Nexus等)の検討

CI/CDでのnpmセキュリティ

CI/CDパイプラインでのnpmセキュリティ対策を紹介します。

対策 実装方法 効果
npm ci使用 npm installの代わりにnpm ciを使用 ロックファイルに厳密に従う
npm audit実行 ビルド時にnpm auditを自動実行 脆弱性検出
ignore-scripts --ignore-scriptsオプション postinstallスクリプト無効化
キャッシュ活用 node_modulesをキャッシュ ビルド高速化、外部依存削減
npm ciコマンド
package-lock.jsonに記載された正確なバージョンをインストール。package.jsonとの不整合があればエラー終了。CI/CD環境に最適。
--ignore-scriptsオプション
postinstall等のスクリプト実行を無効化。悪意あるpostinstallスクリプトの実行を防止。ただし、ネイティブモジュールのビルドが必要なパッケージは動作しなくなる可能性あり。
Socket、Snykとの連携
サードパーティのセキュリティサービスをCI/CDに統合。悪意あるパッケージをリアルタイム検出。「既知の脆弱性」だけでなく「不審な振る舞い」も検出。

シークレット漏洩を防ぐため、npmrcファイルに認証トークンを直接記載しないよう注意してください。環境変数やシークレット管理サービスを活用しましょう。


関連する攻撃手法

npm関連の攻撃は、以下の攻撃手法と組み合わせて実行されることがあります。

攻撃手法 npm関連での例
タイポスクワッティング 人気パッケージの誤字版を公開
依存関係混乱 内部パッケージ名と同名を公開レジストリに登録
依存関係の脆弱性 npmパッケージの既知脆弱性を悪用
ソフトウェアサプライチェーン攻撃 正規パッケージへのバックドア混入
パスワードリスト攻撃 メンテナーのnpmアカウント乗っ取り
フィッシング詐欺 メンテナーの認証情報窃取
クリプトジャッキング 悪意あるパッケージで暗号通貨マイニング

よくある質問

Q: npmパッケージはすべて危険ですか?
A: いいえ、npmパッケージの大多数は安全であり、有用なものです。問題は、200万以上のパッケージの中に悪意あるものが混入している可能性があること、そして依存関係の複雑さから把握が困難なことです。リスクを理解した上で、ロックファイルの活用、npm auditの実行、信頼できるパッケージの選定を行えば、安全に利用できます。
Q: yarnやpnpmでも同じリスクがありますか?
A: はい、同様のリスクがあります。yarn、pnpmもnpmレジストリ(npmjs.com)からパッケージを取得するため、タイポスクワッティングや悪意あるパッケージのリスクは共通です。ただし、各ツールにはセキュリティ機能の違いがあります。例えばyarn 2+(berry)はPnP(Plug'n'Play)でnode_modulesを使わない設計です。pnpmは厳格な依存関係管理を提供します。いずれの場合も、ロックファイルの活用と脆弱性スキャンは必須です。
Q: プライベートレジストリを使うべきですか?
A: 大規模な組織や、セキュリティ要件が高い場合はプライベートレジストリの導入を検討すべきです。npm Enterprise、Verdaccio、Artifactory、Nexusなどが選択肢としてあります。メリットとして、外部レジストリの障害時も影響を受けない、パッケージの検証後にのみ利用許可できる、内部パッケージの安全な配布などがあります。一方、運用コストも発生するため、組織の規模と要件に応じて判断してください。
Q: 依存パッケージの数を減らすべきですか?
A: 依存パッケージの数を意識的に管理することは重要です。「left-pad問題」のように、数行で実装できる機能のために外部パッケージに依存することは、リスクとコストのバランスが悪い場合があります。ただし、複雑な機能を自前実装するよりも、信頼できるOSSを利用する方が安全な場合もあります。各パッケージの必要性、メンテナンス状況、代替手段を評価した上で判断してください。
Q: postinstallスクリプトは無効化すべきですか?
A: 完全な無効化(--ignore-scripts)は、ネイティブモジュールのビルドが必要なパッケージ(node-sass、bcrypt等)で問題を引き起こす可能性があります。代替として、信頼できるパッケージのみpostinstallを許可するホワイトリスト方式、CI/CD環境でのみ無効化する方式、Socketなどでpostinstallの振る舞いを事前検証する方式があります。

まとめ

本記事では、npmエコシステムにおけるサプライチェーン攻撃対策について解説しました。主なポイントは以下の通りです。

  • npmエコシステムは200万以上のパッケージを持つ世界最大のレジストリだが、サプライチェーン攻撃のリスクも高い
  • タイポスクワッティングは人気パッケージのタイプミスを狙った攻撃。パッケージ名の慎重な確認が必要
  • postinstallスクリプトの悪用で、インストール時に悪意あるコードが実行される可能性がある
  • メンテナー乗っ取り(event-stream事件等)は最も深刻な攻撃手口
  • ロックファイル(package-lock.json)の活用とnpm ciの使用が基本対策
  • npm auditで脆弱性を定期的にスキャンし、CI/CDに組み込む
  • スコープパッケージやプライベートレジストリで依存関係混乱のリスクを軽減

次のステップとして、企業間データ連携のセキュリティを解説したサプライチェーン攻撃とEDI|データ連携のアクセス制御と秘密保持をご参照ください。

技術者向けカテゴリの全体像については、サプライチェーン攻撃の技術対策|SBOM・CI/CD・OSS・EDIをご覧ください。

サプライチェーン攻撃の総合的な理解には、サプライチェーン攻撃とは|仕組み・事例・対策を初心者にもわかりやすく解説もあわせてご参照ください。


重要なお知らせ

  • 本記事は一般的な情報提供を目的としており、個別の状況に対する助言ではありません。
  • 実際にサイバー攻撃の被害に遭われた場合は、警察(#9110)やIPA(03-5978-7509)などの公的機関にご相談ください。
  • 法的な対応が必要な場合は、弁護士などの専門家にご相談ください。
  • 記載内容は作成時点の情報であり、攻撃手法は日々進化している可能性があります。

サプライチェーン攻撃 完全ガイド ナビゲーション

総合ガイド

目的別に探す

役職・立場別に探す

技術対策(技術者向け)

業種別に探す

人気のページ

更新履歴

初稿公開

京都開発研究所

システム開発/サーバ構築・保守/技術研究

CMSの独自開発および各業務管理システム開発を行っており、 10年以上にわたり自社開発CMSにて作成してきた70,000以上のサイトを 自社で管理するサーバに保守管理する。