fbpx

npmの新たな欠陥:アカウント乗っ取りを目的としたパッケージ #aqua #argon #セキュリティ #npm

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本ブログは「Aqua Security」社の技術ブログで2022年4月5日に公開された「 New npm Flaws Let Attackers Better Target Packages for Account Takeover 」の日本語翻訳です。

npmの新たな欠陥:アカウント乗っ取りを目的としたパッケージ


ここ数年、サイバー犯罪者がメンテナーのアカウントを乗っ取って、人気のある npm パッケージを侵害するという事件が発生しています。Aqua のセキュリティ研究チームである Team Nautilus の研究の一環として、私たちは、npm のプラットフォームに、2要素認証(2FA)に関連する2つの欠陥を発見しました。攻撃者はこれらの欠陥を利用して、npm パッケージをターゲットにしてアカウント乗っ取り攻撃ができます。私たちはこの発見を npm チーム(GitHub)に報告し、npm チームはすぐに根本的なセキュリティギャップを修正しました。

しかし、我々の分析によると、上位35の npm パッケージのうち 32% はまだアカウント乗っ取りされる危険性がありました。これにより、攻撃者はルートパッケージや、それらの人気パッケージに依存する他の npm パッケージを汚染し、その結果、数百万人の npm ユーザに影響を与える可能性があります。このブログでは、調査の詳細を探り、npm パッケージの直接依存と推移的依存のセキュリティリスクについて検証していきます。

npmとJavaScript

「2021 Stack Overflow Developer Survey」によると、最も使われているプログラミング言語は、9年連続で JavaScript です。65% の開発者が過去1年間にこの言語を使用したことがあるそうです。

npm に馴染みのない方のために説明すると、それは Node Package Manager の略です。基本的には、Node JavaScript プラットフォーム用のパッケージマネージャーです。npm は、何百万人もの開発者がコードを公開し共有するために使用している世界最大のソフトウェアレジストリです。


2021 Stack Overflow Insights

今日、開発者はソフトウェア開発プロセスを通じてサードパーティのオープンソースパッケージを多く使用しているため、ソフトウェアサプライチェーン攻撃のリスクにさらされています。

npm のような一般的なパッケージマネージャーとそのユーザは、サプライチェーン攻撃の標的にされることが多くなっています。通常、攻撃者は悪意のあるコードを良性のパッケージ、またはその直接的・推移的な依存関係のいずれかに直接埋め込みます。

悪名高い例として、毎週数百万回ダウンロードされている npm パッケージである UA-Parser-JS がありますが、これはクリプトとパスワード流出マルウェアに汚染されたため、その後すぐに更新されました。

これはどの程度の問題だったのでしょうか。最近のレポートによると、ソフトウェアサプライチェーン攻撃は、2020年の前年比 430% 増に加え、2021年には 650% 増となり、攻撃者は良性のパッケージに悪意のあるコードを注入しているとのことです。

npm の様々な悪用方法と弱点についてもっと知りたければ、「What are Weak Links in the npm Supply Chain?」という素晴らしい記事は読む価値があります。

攻撃者は、いくつかの方法で目的のパッケージへのアクセスが可能です。1つの方法は、パッケージメンテナーの資格情報の1つを取得することです。

2017年に発表された研究では、あるセキュリティ研究者は、全 npm パッケージの 14% に直接アクセスできました(そして、54% のパッケージへ間接的にアクセスできました)。攻撃者はブルートフォース攻撃を使用したり、他の侵害で発見されたパスワードを再利用したりして、npm ユーザ全体で大量のパスワードリセットを引き起こしました。

npm の構造上、乗っ取られたパッケージや悪意のあるパッケージがあると、広範囲に影響を及ぼします。npm は単一の問題を解決する小さなパッケージの作成を推奨しています。このため、他のパッケージに依存する小さなパッケージが多数存在することになります。

上記の認証情報漏洩の研究の結果、研究者は最も広く使用されているパッケージのいくつかにアクセスでき、他の方法ではアクセス不可能な範囲より、はるかに広い範囲の価値あるパッケージへアクセス可能となりました。

例えば、2022年4月時点で週平均2,500万回ダウンロードされている npm の人気トップ10パッケージの1つである express の依存関係グラフが上図となります。

攻撃者は、express の直接依存関係や推移的依存関係にアクセスすることで、パッケージ全体を危険にさらす可能性があります。

依存関係の固定化、package-lock.json、公開済みパッケージの上書き不可など、依存関係の1つによってルートパッケージに影響を及ぼす可能性のある考慮すべき点がいくつかあるため、現実はより複雑です。Matthew Bryant 氏は、「"Zero-Days" Without Incident - Compromising Angular via Expired npm Publisher Email Domains」でそのうちのいくつかをレビューしています。

2019年の調査では、平均してパッケージは 79 のサードパーティパッケージと 39 のメンテナーを暗黙のうちに信頼していることがわかりました。さらに、人気のあるパッケージは、10万以上の他のパッケージに影響を与えていることが多く、攻撃の格好のターゲットになっています。

npmのセキュリティに特化した改良

npm のセキュリティは、コミュニティがそのセキュリティリスクを認識するようになったため、時間の経過とともに改善されてきました。

2022年2月から、npm は依存関係でトップ100の npm パッケージのすべてのメンテナーに対して 2FA を要求しています。

また、週間ダウンロード数が100万以上、または依存関係が500以上のパッケージである影響範囲が広いパッケージについても、2FA を要求する予定です。

メンテナーにとって 2FA が重要なのは、漏洩したパスワードに関連するリスクを即座に減らすことができるからです。パスワードが漏えいしたり、推測されたり、あるいはフィッシングされたりした場合でも、侵入者がアクセスを成功させるには不十分です。2つ目の要素の確認がなければ、パスワードは役に立ちません。

さらに、npm はログイン認証の強化を開始しました。ログインを許可するために、追加の認証を要求します。2FA を有効にしていない場合、アカウントに関連付けられたメールアドレスへワンタイムパスワードが送信されます。

しかし、ワンタイムパスワードだけでは強度が足りないため、2FA を設定することは常により強力なプラクティスです。npm のパスワードが漏えいしたのであれば、プライベートなメールアカウントのパスワードも漏えいしている可能性があります。多くの場合、同じパスワードが使われているため、攻撃者はあなたのメールに送られたワンタイムパスワードをバイパスできます。

これらの改善は、セキュリティの観点からはすべて良いニュースです。パッケージのホスティング、新バージョンのリリース、npm アカウントへのサインインに 2FA を持たないメンテナーは、ソフトウェアのサプライチェーンにおいて弱点となります。

「A chain is only as strong as its weakest link」という言葉があるように、チェーンは最も弱いリンクがそのリンクの強度となります。パッケージのセキュリティを確保するために、パッケージの直接依存関係や推移的依存関係のメンテナーにも同じ要件を強制する必要があります。

npmの情報公開:2FAの一覧

私たちの研究では、メンテナーが 2FA を強制的に有効にした人気の npm パッケージのうち、直接および推移的依存関係のメンテナーが 2FA を使用していないため、アカウントを乗っ取られる危険性が残っているパッケージはどれだけあるかを調べようとしました。

私たちの最初の課題は、npm のユーザが 2FA を有効にしているか無効にしているかを判断することでした。だいたいはこのような情報はすべてのユーザが入手できるものではないはずです。

しかし、それを発見する簡単な方法が判明しました。パッケージの作成者として、どんな npm ユーザもメンテナーとして追加できます。

  • npm パッケージの作成と公開
  • https://www.npmjs.com/package//access にあるパッケージ設定ページを参照
  • 2FA 化している npm ユーザを一覧化し、メンテナーとして追加

ユーザの 2FA の状態は、メンテナーウィンドウに表示されます。

この機能は、開発者を保護するためのもので、ユーザをパッケージのメンテナーとして追加する際に、いかに安全であるかを示すためのものです。しかし、それが悪用されることもあります。

2022年2月、HackerOne の GitHub のバグバウンティプログラムを通じて、npm のスタッフにこれらの問題を報告したところ、「以前に確認された問題であり、社内で追跡調査中です。改善に向けて積極的に取り組んでいます」と回答頂きました。

2022年3月、この修正がロールアウトされ、npm はメンテナーの 2FA ステータスを表示しなくなりました。

npmの情報公開:「enforced tfa」の一覧化

調査の一環として、特定のメンテナーが 2FA の使用を義務付けているか、また、ある組織が従業員に 2FA の使用を義務付けているかを判断する方法を見つけました。

未認証のユーザでも、他の npm ユーザや組織で「enforced_tfa」が有効になっているかどうかを調べたり、そのユーザがスタッフかどうかやその他の詳細を調べられるのです。

npm のすべてのユーザまたは組織のプロファイルにこの情報が含まれていることに驚きました。

以下は、再現手順です。

  1. https://www.npmjs.com/~ または https://www.npmjs.com/org/ にリクエスト
  2. リクエストのレスポンスを表示
  3. window.context json の 'enforced_tfa' と 'isStaff' の値を抽出する。

例えば、Facebook(fb user)は、npm によって 2FA を有効にすることを要求していることがわかります。

HackerOne の GitHub のバグバウンティプログラムを通じて、npm の担当者に以下の問題を報告しました。この問題は検証され、修正されました。

「enforced tfa」の一覧化のための情報開示のタイムライン

  • 14-02-2022:この問題は、HackerOne にある GitHub のバグバウンティプログラムに報告されました。
  • 14-02-2022:GitHub から、この問題を調査しているという最初の回答がありました。
  • 17-02-2022:GitHub のセキュリティチームがこの問題を確認しました。
  • 25-03-2022:npmjs.com で問題が修正されました。

npm調査:技術的な詳細

ユーザが 2FA を有効にしているかどうかを判断する方法ができたので、パッケージの依存先のメンテナーからアカウントが乗っ取られる危険性のある(2FA が有効になっていない)上位 npm パッケージの割合を計算できます。

以下の条件を両方満たした場合、ユーザはリスクがあると判断されます。

  • 2FA が実施されていない
  • 古い/現在のパスワードが流出した

これを判断するために、haveibeenpwned API と「enforced_tfa」メソッドを使用して、enforce 2FA を有効化している npm ユーザのを一覧化することにします。

その結果を要約する短い Python スクリプトを書きます。プロセスを単純化するために、2022年2月時点の上位35の npm パッケージ(npmjs.com に表示)でスクリプトを実行し、依存関係メンテナーの enforce 2FA ステータスとパスワード漏洩ステータスを確認することにします。

enforced_2fa 変数から false 値が返された場合、必ずしもそのユーザが 2FA を有効にしていないという意味ではないことに注意してください。しかし、この研究では、潜在的なリスクを評価できるように、このユーザをまだ 2FA を有効にしていないメンテナーとして扱います。

また、パッケージが他のパッケージの特定のバージョンに依存している場合でも、攻撃者はその依存関係に影響を与えることができないことを覚えておくことが重要です。しかし、多くの場合、これは脆弱なパッケージがパッチを当てられないまま放置されるなど、別の問題を引き起こす可能性があります。

また、パッケージは通常、パッチやマイナーリリースを示す ~/^ シンボルを使ってそのバージョンに依存しています。このため、攻撃者は依存するパッケージに直接影響を与えるようなパッチやマイナーリリースを施した悪意のあるパッケージをプッシュする機会を与えてしまいます。

さらに、あるパッケージが他のパッケージの特定のバージョンを必要とする場合でも、メンテナーのアカウントの1つを制御する攻撃者は、そのパッケージを脆弱性としてマークし、下流のパッケージを攻撃者の悪意のあるパッケージのバージョンにアップデートするようプッシュできます。

この影響については、Matthew Bryant 氏が「“Zero-Days” Without Incident - Compromising Angular via Expired npm Publisher Email Domains」という記事で詳しく解説しています。

調査を簡単にするため、少なくとも1つのルートで依存パッケージが悪意のあるコードでルートパッケージを更新できる場合、そのパッケージを危険と判断しました。

上記のコードを実行した後、上位35の人気 npm パッケージについて、以下のデータを得ました。結果は2022年2月を参照しており、詳細な統計はAppendixでご覧いただけます。

npm調査:統計分析

我々の分析によると、上位35の npm パッケージの 32% は、依存関係の所有者からアカウントを乗っ取られる危険性が残っており、攻撃者がルートパッケージを悪用することを可能にしています。

また、devDependencies に関しては、結果が深刻になる可能性があることに注意が必要です。

実際、devDependencies の結果は、72% の暴露率を示しています。つまり、これらの devDependencies のメンテナーが 2FA を有効にしておらず、ルートパッケージがこれらの依存関係の特定のバージョンを使っていない(すなわち、ルートパッケージが ~/^ シンボルを使っている)ということです。

devDependencies のダウンロード平均は、本番用依存ファイルと比較して高くはなく(100万ダウンロード未満)、また、そのメンテナーは npm によって 2FA 要求されていません。

以下の攻撃ベクトルでは、攻撃者はルートパッケージのメンテナーのワークスペースに直接アクセス可能です。

また、この結果は、特定の人気パッケージの直接のメンテナーよりも間接のメンテナーが多い場合は常に、そのパッケージが危険にさらされていることを示唆しています。この比率は数十倍にもなり、body-parser パッケージの場合は125倍にもなるケースがあります。

メンテナーが多いパッケージは、アカウント乗っ取りやソーシャルエンジニアリング攻撃の対象が増え、その機会を多く提供します。これは devDependencies パッケージと同様に、直接および間接的な依存関係にも当てはまります。

msパッケージ:コミュニティが広ければ広いほど、リスクも大きくなる

さて、ms パッケージについてもう少し詳しく見てみましょう。このパッケージは様々な時間フォーマットをミリ秒に変換するもので、比較的小さなものです。2022年4月現在、このパッケージは週に 1.64億回ダウンロードされ、約3200の依存パッケージがあります。

このパッケージの主な問題は、メンテナーの数が多いことで、約130人もいます。

パッケージが特定のバージョンに依存していない場合、深刻な危険にさらされる可能性があります。例えば、humanize-ms パッケージ(週間ダウンロード数が600万回)は ms ^2.0.0 バージョンに依存しています。

攻撃者は、メンテナーのプロフィールの1つを侵害することで身元を隠し、大規模であるがために生じる見落としにつけ込むことができます。多くのメンテナーが居ることで、より監視が強化されるというオープンソースの本質も一理ありますが、限界もあるはずです。

因みに、ms パッケージのメンテナーの約66%はまだ 2FA を導入しておらず、さらにはパスワードのバリエーションが以前漏えいしています。

間接的なメンテナーのアカウント乗っ取りリスクを回避するもう1つの方法は、依存関係を「ピン留め」することです。例えば、デバッグパッケージの間接的なメンテナの 78% はリスクにさらされています。しかし、ルートパッケージ(デバッグパッケージ)は package.json ファイルにある依存関係の絶対バージョンを使っているため、影響を与える方法がありません。

npm が100万ダウンロード以上のパッケージの全メンテナーに対して 2FA を強制すれば、上記のリスクは改善されるでしょう。

極限まで高める:no-one-left-behind パッケージ

「no-one-left-behind」というパッケージをご存知でしょうか。2018年から1000近い npm パッケージに依存しています。このパッケージがどれだけの依存関係や間接的な所有者を持ち、どれだけの影響を受けるか想像してみてください。もちろん、これは依存関係の極端な例ですが、ポイントをよく表しています。


”no-one-left-behind" パッケージの依存関係グラフ

まとめ


近年、オープンソースプロジェクト、特に npm のセキュリティは向上しています。しかし、攻撃者もその手法やツールを進化させています。

防御側とは対照的に、攻撃者はたった1つの成功(この場合は1つの危険なパッケージ)だけで、攻撃のキルチェーンを立ち上げることができるのです。

私たちの調査によると、多くのメンテナーを抱える npm パッケージは、悪用されるリスクが高いです。開発者はこのことを考慮し、少なくとも依存関係を固定しながら使用する必要があります。

攻撃対象領域を最小化し、攻撃者にとってアカウント乗っ取りをより困難にすることは、開発者である私たち次第です。そうでなければ、コミュニティ全体にダメージを与える結果になりかねません。

最後に、オープンソースに貢献し、パッケージを作成する開発者には、コミュニティを安全に保つために、すべてのアカウントで 2FA を有効にすることを強くお勧めします。

GitHub/npm のセキュリティチームの迅速な対応と専門的な修復プロセスに感謝します。

Argon はどのように役立つのか

  • Argon のソリューションは、使用中のオープンソースパッケージの様々な異常を特定し、このブログで紹介されているような不審な行動を検出できます。
  • Argon はソフトウェアのサプライチェーンに可視性を提供し、組織の 2FA ポリシーからの逸脱をチームに通知します。

  • Argon は、コードの脆弱性だけでなく、組織内の設定ミスやセキュリティポリシーの不備についてもチームに警告できます。

Appendix

New call-to-action

新規CTA