はじめに
目的
この文書は、CDN(コンテンツ配信ネットワーク)を経由して配信されるnpmパッケージの仕組みと、それに伴うセキュリティリスクを分かりやすくまとめたものです。実務での注意点や具体的な攻撃例、対策まで一貫して解説します。
対象読者
開発者、運用担当者、セキュリティ担当者を想定しています。専門知識が深くない方にも理解できるよう、専門用語は最小限にして具体例で補足します。
読み方のポイント
各章は順を追って読めば理解が深まります。第2章で基本を押さえ、第3〜6章で攻撃手法や事例を確認し、第7章で実践的な対策を学べます。
用語と補足例
CDN:世界中のサーバーからファイルを配る仕組み。例えば、ライブラリの配信用のサーバーと考えてください。npmパッケージ:JavaScriptの部品で、アプリに組み込んで使います。
本書を通じて、安全な配信と運用の理解を深めていただければ幸いです。
CDNによるnpmパッケージ配信の基本的な仕組み
CDNとは
CDN(コンテンツ配信ネットワーク)は、世界中に分散したサーバー群を使ってファイルを高速に届ける仕組みです。利用者に近いサーバーから配信するため、読み込みが早くなります。例えば日本の利用者には日本のサーバーから送られます。
npmパッケージの配信の流れ
- 開発者がnpmに公開したパッケージは、CDNがnpmレジストリから取得して配信します。ブラウザーはCDNのURLを指定して直接ファイルを読み込みます。
- 典型的にはタグやimport文でCDNのURLを指定します。これによりローカルにダウンロードせずにライブラリを使えます。
よく使われるURL例
- https://cdn.jsdelivr.net/npm/react@17/umd/react.production.min.js
- https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
これらはpackage-name@versionの形式が多く、バージョンを指定すると同じファイルが返ります。
キャッシュとバージョン管理
CDNはキャッシュを強く効かせるため、同じバージョンは長く保存されます。バージョンを指定しない(latestなど)と、意図せず更新が反映されることがあります。安定性を高めるには明示的にバージョンを固定してください。
配信の利点と注意点
利点は高速化と運用の簡便さです。注意点としては、配信元URLの指定ミスやバージョン未固定で予期せぬ変更が起きること、配信経路の可視化が必要な点です。HTTPSで配信されるため改ざんリスクは下がりますが、依存先の管理は重要です。
CDNインフラを悪用した新型フィッシング攻撃
概要
近年、攻撃者はnpmとHTTPS対応のCDN(例: unpkg.com)を組み合わせて、無料かつ信頼された配信インフラを悪用する手口を確認しています。特徴的なのは「redirect-xxxxxx」のようにランダム6文字を含むパッケージ名を公開し、CDN経由のURLでフィッシングページを配信する点です。
具体例(イメージ)
攻撃者はパッケージ名を redirect-abc123 のように付け、index.htmlやlogin.htmlを含めてnpmに公開します。すると次のようなHTTPS URLで直接アクセスできます。
このURLをフィッシングメールやチャットで送れば、受信者は一見安全なunpkg.comドメインを信用してアクセスし、偽のログイン画面に誘導されます。
なぜ効果的か
- CDNがHTTPSで配信するため、ブラウザの鍵アイコンやTLSが有効に見える。信頼度が高く見えます。
- パッケージ自体はインストール時に悪意ある処理を行わない設計で、従来のインストール時スキャンを回避します。
- パッケージ名にランダム文字列を使うため、自動検出やブロックリストに載りにくいです。
- CDNのキャッシュや世界配信により、コンテンツの削除後も一時的に残る場合があります。
検出の難しさと注意点
配布元がunpkg.comのような正当なドメインのため、メールやSNSのフィルタをすり抜けやすいです。さらに、ダウンロード数や依存関係に異常が出ないケースもあり、見つけにくいです。
予防的な対策(簡易)
- 見慣れないリンクはブラウザで直接開かず、まずパッケージのnpmページを確認する。ファイル一覧を確認すると中身が見えます。
- 怪しいログイン画面には絶対に認証情報を入力しない。公式サイト経由で再度ログインする習慣をつける。
- 組織ではURLのホワイトリスト運用や、疑わしい外部リンクの自動検査を導入してください。
以上が、CDNインフラを悪用した新型フィッシング攻撃の仕組みと注意点です。次章では攻撃チェーンと配信メカニズムを詳しく見ていきます。
攻撃チェーンと配信メカニズム
攻撃開始:パッケージ公開とCDNホスティング
攻撃は、悪意あるnpmパッケージを公開することから始まります。unpkg.comのようなCDNは公開されたパッケージを自動的にホストするため、攻撃者は追加のインフラを用意せずに悪意あるスクリプトを配信できます。
被害者への配布とロードの仕組み
攻撃者は購買注文書やプロジェクト文書を装ったHTMLファイルを配布します。被害者がファイルを開くと、埋め込まれたJavaScriptがCDN上の悪意あるパッケージを読み込みます。読み込みは正規のCDNドメイン経由で行われるため、受信者は不審に思いにくいです。
フィッシングページと認証情報の収集
読み込まれたスクリプトは被害者をフィッシングページにリダイレクトします。このページは認証用フォームを表示し、メールアドレスを事前入力して正当性を装います。被害者が入力すると情報は攻撃者へ送信されます。
回避・持続メカニズム
CDN配信とHTTPSにより検出やブロックを避けやすく、攻撃者はパッケージを更新して挙動を変えられます。キャッシュ制御やバージョン指定を悪用して配信を持続させます。
検出のヒントと初動対応
CDNドメインでも不審なスクリプトや外部へのリダイレクト、事前入力されたメールアドレスに注意してください。疑わしい場合はオフラインで内容を確認し、パッケージ名とCDNリクエストをログで追跡してください。
長期間にわたるAiTM(Adversary-in-the-Middle)フィッシングキャンペーン
背景
セキュリティ研究者は1年以上続くAiTMフィッシングキャンペーンを確認しました。攻撃者はnpm、GitHub、パブリックCDNを悪用し、jsDelivr上のnpmパッケージ内ファイルを通じて悪意あるJavaScriptを配信しました。発見された関連パッケージは約60にのぼります。
攻撃の継続手法
攻撃者は数日から数週間ごとに新しいnpmパッケージを公開し、継続的な配信経路を確保しました。パッケージ名やバージョンを変更して追跡を逃れ、CDN経由で正規ファイルに見せかけて悪コードを配布しました。配信は自動化されていたと見られます。
被害の中身(一般例)
配布されたJavaScriptは、ウェブページのログインフォームや認証トークンを傍受する動作を含みます。たとえば、フォーム送信時に入力データを外部サーバに転送したり、セッション情報を書き換えて別サーバへ誘導したりします。
実践的な注意点
- 公開CDN上のライブラリを無条件で信頼しないでください。ファイル改ざんの可能性を念頭に置きます。
- package.jsonやリポジトリの作成履歴を確認し、短期間に大量の類似パッケージが出現していないか監視します。
- 依存関係は固定(バージョンピン)し、可能ならサブリソース整合性(SRI)やコンテンツセキュリティポリシーを導入してください。
- 不審な通信やフォーム挙動はログで検出し、異常があれば即時調査します。
長期間にわたるキャンペーンは検出を遅らせるため、継続的な監視と供給経路の多層防御が重要です。
サプライチェーン攻撃による暗号資産盗難
概要
攻撃者は「support@npmjs.help」からの偽メールでパッケージのメンテナーをだまし、認証情報を盗みました。結果として27個の人気npmパッケージに悪意あるコードが注入され、Web3ウォレットを狙った暗号資産の窃盗が行われました。
フィッシングから侵入まで
攻撃者は信頼できるサポート通知を装い、メンテナーに認証情報を入力させました。これによりnpmのトークンが奪われ、攻撃者は被害者アカウントになりすまして操作できるようになりました。
サプライチェーンの悪用手口
奪ったnpmトークンで、攻撃者は被害者の全パッケージをダウンロードしました。ダウンロードしたパッケージの「preinstall」スクリプトに悪意あるローダーを差し込み、バージョン番号を上げて感染パッケージを再公開しました。ユーザーがそのパッケージをインストールすると、改ざんされたスクリプトが自動で動作します。
マルウェアの働きと暗号資産の盗難
組み込まれたマルウェアは、Web3ウォレット(ブラウザ拡張など)を狙います。具体例として、ウォレット接続の画面を偽装したり、署名や鍵のエクスポートを促すような処理で利用者の資産移動を引き起こします。結果として秘密鍵や種(シード)フレーズ、署名権限が奪われ、暗号資産が不正に送金されます。
被害拡大の仕組み
攻撃者は改ざん済みパッケージを広く再公開することで、開発者や利用者の環境へ素早く広げました。プリインストール段階で実行されるため、利用者が普段通りインストールするだけで感染する点が被害を大きくしました。
(この章は手口の説明に留め、実行手順の詳細は記載していません。)
セキュリティ対策と検出・対応メカニズム
日常的な予防策
- package-lock.jsonを必ず使い、バージョンを固定します。CIではnpm ciでインストールし、整合性チェックを行います。
- 依存関係は定期的に監査します(npm audit、Snyk、Mend.ioなど)。自動更新はテスト付きで段階的に行います。
パッケージと公開者の検証
- 新しいパッケージは公開者情報とメンテナー履歴を確認します。npm viewやレジストリの履歴を参照してください。
- 所有権変更通知を重視し、急な権限委譲は導入しないでください。
配信と実行時の防御
- CDN経由でロードするスクリプトにはサブリソース整合性(SRI)を使います。バージョンピンとハッシュ検証で改ざんを防げます。
- WebではContent Security Policyを設定し、外部スクリプト実行を制限します。
監視と検出
- ネットワークの異常な外部接続や未知ドメインへのリクエストをログ化してアラートを出します。
- API仕様の不審な変更、パッケージの突発的な更新、予期しない依存追加を検出するルールを用意します。
- ウォレット連携は行動分析を導入し、署名要求やトランザクションの異常(大量ガス、トークン承認)でブロックします。
インシデント対応手順
- 影響範囲を特定してサービスを隔離します。
- package-lock.jsonで既知安全なバージョンにロールバックします。
- 秘密情報とAPIキーを無効化し、回復用の鍵をローテーションします。
- レジストリやCDN事業者へ報告し、悪意あるパッケージを削除依頼します。
- ログとアーティファクトを保存し、原因分析を行います。
ツール活用のヒント
- Mend.ioやSnykで脆弱性と悪意ある署名を検出します。
- GitHub Actionsで依存差分や所有権変更を自動チェックします。
導入しやすい対策を優先し、小さなステップで堅牢性を高めてください。












