npmパッケージのエイリアス機能を利用した依存関係混乱攻撃の拡張を探る
Nishant Jain
2021年11月4日
0 分で読めます依存関係混乱攻撃は、パッケージマネージャーによる依存関係のインストール方法を悪用する、オープンソースのサプライチェーンを狙った攻撃の一種です。以前の記事では、サプライチェーンのセキュリティを維持するために、npmで依存関係混乱攻撃を検出・防止する方法を紹介しました。
この記事では、npmのパッケージエイリアス機能を利用した、依存関係混乱の問題を拡張する手法を紹介します。npmのコマンドラインアプリケーションで提供され、利用方法が説明されているこの機能を使うと、ユーザー側でパッケージを別のエイリアス名でインストールできます。npmの公式ドキュメントにある次の例をご覧ください。
これにより、次のpackage.jsonエントリが作成されます。
npmのパッケージエイリアスによる影響は、他のパッケージ関連ツールがパッケージマニフェストをどう扱うかに表れます。実際には、npmjs.orgの公式レジストリ自体にも当てはまります。この攻撃シナリオに直接的なセキュリティ上の影響はありません(エイリアスされたパッケージは、npmコマンドで指定されたバージョンを必ずダウンロードするため)。しかし、他の攻撃経路が生まれる余地を広げると考えています。
npmパッケージのエイリアスを利用した攻撃シナリオ
npmパッケージのエイリアス攻撃がもたらす影響を再現し、依存関係混乱や悪意のある不正パッケージのインストールにつながる可能性を示します。
まず、deneuve-package-parentという名前のパッケージを作成し、deneuve-package-testパッケージの異なる2つのバージョン(1.0.0と1.2.0)をインストールします。1.0.0は、npmのパッケージエイリアス機能により、架空のパッケージ名deneuve-package-privateのエイリアスとしてインストールされます。
npmjs.comでは、これがdeneuve-package-parentの依存関係の1つとして解析されます。
上記で説明したパッケージ依存関係ツリーの全体像を示す、次のpackage.jsonをご覧ください。
このパッケージをnpmjsに公開し、依存関係の一覧を確認しました。
ご覧のとおり、npmjsレジストリの依存関係一覧では、架空のエイリアスdeneuve-package-privateが依存パッケージ名の1つとして表示されています。

上のスクリーンショットには、deneuve-package-privateという依存関係が表示されています。これはpackage.jsonでエイリアスとして設定したもので、実際の依存関係ではありません。このエイリアス(パッケージ名として使用)は、npmjsレジストリには実在しません。誰かが公開しない限りは。そして、ここにサプライチェーンセキュリティ上の懸念が生じます。

ここで疑問が浮かびます。誰かがこのようなエイリアスパッケージを見つけ、悪意のあるパッケージとしてnpmに公開したらどうなるでしょうか。混乱したユーザーは、npmjsの公式パッケージページに記載された依存関係を目にし、開発マシンでローカルにnpm installを実行するだけで、そのパッケージを利用してしまう可能性があります。
開発者がアプリケーションのデバッグ中に、各ライブラリを個別にダウンロードしようとすれば、このシナリオが起こり得ます。実際のところ、ダウンロードするパッケージがプライベートなものかどうかを、開発者はどれほど確認しているでしょうか。単純なミスや見落としがあれば十分に起こり得ます。スコープのないパッケージのダウンロードを禁止するポリシーがある企業でも例外ではありません。
この名前で空のパッケージをnpmjsレジストリに公開しました。Dependentsタブを見ると、このパッケージをエイリアスとして参照している依存パッケージの1つから、元のパッケージへリンクされていることがわかります。

これは、npmjsレジストリをはじめ、パッケージ名を扱うあらゆる開発者向けツールへの注意喚起と捉えるべきです。パッケージ名についてユーザーを混乱させないようにする必要があります。
タイポスクワッティングによるパッケージ名の悪用が今も有効なサプライチェーン攻撃の手段であることからも、パッケージのエイリアスに見られるような、わずかな正当性の印象でさえ、攻撃の成功率を大きく高める可能性があるとわかります。
この発見に至った経緯
この種のサプライチェーン攻撃は、私とセキュリティ研究者のMario Stathakoが最近発見し、GitHubとnpmに報告しました。私はバグバウンティに関するセキュリティリソースの調査と開発に取り組む大学院生です。また、Snyk Ambassadorでもあります。Marioはペネトレーションテスターで、Capture the Flag(CTF)やバグバウンティプログラムに定期的に参加しています。
Dependency Confusionに興味を持ったのは、とても単純な問題でありながら、大きな影響を及ぼすものだったからです。そこでMarioと私は、HackerOneの非公開プログラムでこの問題を探し始めました。よく知られた調査結果が発表されてから一定期間が経過した後、企業がどれほど効果的に対応・緩和しているかを確認したかったのです。攻撃用のPOCパッケージを作成する中で、NPMのWebサイトに奇妙な挙動を見つけました。パッケージごとにpackage.jsonファイルの処理方法が異なり、そのパッケージの被依存関係と依存関係の表示にも差があったのです。
サプライチェーンセキュリティのリスクから身を守る
Snykは、依存関係混乱攻撃や関連する攻撃の可能性を検出して警告する、オープンソースのコマンドラインアプリケーションsnyncを開発・公開しました。このツールについて詳しくは、npmの依存関係混乱の検出と防止に関するブログをご覧ください。
さらに、Snyk Advisorはパッケージのバージョンごとのセキュリティ問題を見つけるのに役立ち、悪意のあるパッケージと判定された場合は明確に表示します。

最後に、オープンソースのサプライチェーンセキュリティに関するベストプラクティスを学ぶため、次の記事もおすすめします。
CTFを始めよう
オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。
