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(スコープなし) |
検出方法
タイポスクワッティングを検出・防止する方法を紹介します。
- パッケージ名の慎重な確認:インストール前に公式ドキュメントやnpmjs.comでパッケージ名を確認
- npm auditの活用:既知の悪意あるパッケージを検出。定期的に実行
- Socketなどのセキュリティサービス:悪意あるパッケージをリアルタイム検出
- ロックファイルの活用:一度検証したパッケージを固定し、予期しないパッケージを防止
悪意あるパッケージの手口
タイポスクワッティング以外にも、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のたびに「最新」バージョンがインストールされ、悪意あるバージョンがリリースされた直後にインストールされる可能性がある。
- package-lock.jsonをリポジトリにコミットする
- CI/CD環境では「npm ci」コマンドを使用(ロックファイルに従って厳密にインストール)
- 依存関係の更新は計画的に実施し、更新後にテストを実行
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)などの公的機関にご相談ください。
- 法的な対応が必要な場合は、弁護士などの専門家にご相談ください。
- 記載内容は作成時点の情報であり、攻撃手法は日々進化している可能性があります。
サプライチェーン攻撃 完全ガイド ナビゲーション
総合ガイド
目的別に探す
役職・立場別に探す
技術対策(技術者向け)
- SBOM
- CI/CD・SLSA
- OSSセキュリティ
- npmセキュリティ(現在のページ)
- EDIセキュリティ
- 脅威モデリング
業種別に探す
人気のページ
更新履歴
- 初稿公開