NPM の根幹を揺るがす Manifest Confusion:パッケージ情報が信頼できない理由

NPM ecosystem at risk from “Manifest Confusion” attacks

2023/06/28 BleepingComputer — NPM (Node Package Manager) レジストリには、Manifest Confusion と呼ばれるセキュリティ上の欠陥が存在する。具体的に言うと、それにより、依存関係を用いたマルウェアの埋め込みや、インストール中における悪意のスクリプトの実行などが生じ、パッケージの信頼性が損なわることになる。NPM は、JavaScript プログラミング言語用のパッケージ・マネージャであり、広く使用されている Node.js のデフォルト環境である。このパッケージ・マネージャーは、npmjs.com に置かれた npm registry データベースにホストされている、ソフトウェア・パッケージのインストール/アップグレード/コンフィグレーションを、プロジェクト・オーナーが自動化できるよう支援するものである。


このプラットフォームは GitHub を介して、2020年に Microsoft に買収され、現在では世界の 1,700万人以上のソフトウェア開発者が利用し、毎月 2,080億のパッケージをダウンロードしていると推定される。

GitHub の元エンジニアである Darcy Clarke は、自身のブログで Manifest Confusion の問題を取り上げており、遅くとも 2022年11月以降において、この問題を GitHub は認識していたが、関連するリスクへの対処はほとんど行われてこなかったと説明している。

また、NPM レジストリは、アプリケーションの機能を拡張するために使用できる、広範なパッケージを揃えており、開発者たちの作業を大幅に削減するため、絶大な人気を誇っている。

しかし、その人気の高さゆえ、悪意のパッケージを配布することで、開発者のコンピュータの乗っ取り、および、認証情報の窃取、ランサムウェアの展開などを試みる、脅威アクターたちの格好の標的となっている。

Manifest Confusion

Manifest Confusion とは、パッケージのマニフェスト情報とファイルとの間に、矛盾がある場合に発生する。具体的には、npm レジストリに提示されたパッケージのマニフェスト情報と、パッケージのインストール時に使用される公開 npm パッケージ “tarball” 内の、実際の “package.json” ファイルとの不一致による問題である。

パッケージの公開時に npm に提出されるマニフェスト・データと “package.json” の双方に含まれるのは、パッケージ名/バージョンおよび、デプロイに使用されるスクリプトやビルドの依存関係などのメタ・データなどである。

マニフェスト情報とファイルは、別々に npm レジストリに提出されるが、このプラットフォームでは両者の一致/不一致が検証されないため、両者のデータが異なる可能性が生じる。つまり、内容を精査しない限り、不一致があっても限り誰にも分からないという。

そのため、脅威アクターたちは、新しいパッケージと一緒に提出したマニフェスト・データを修正し、依存関係やスクリプトを削除し、それらが nmp レジストリに表示されないようにできる。しかし、これらのスクリプトや依存関係は、依然として “package.json” ファイルに存在するため、パッケージがインストールされると、それらが実行されることになる。

この Manifest Confusion は、以下の画像に示されるとおり、package.json には依存関係が記載されているが、Darcy Clarke の PoC パッケージの npm には、依存関係はゼロであると記載されている。

Example of manipulated manifest data
Example of manipulated manifest data (blog.vlt.sh)

Manifest Confusion から生じるリスクに含まれるものとしては、キャッシュ・ポイズニング/未知の依存関係のインストール/未知のスクリプトの実行/ダウングレード攻撃などが挙げられる。

Socket の CEO である Feross Aboukhadijeh は、「はっきりさせておくが、これは隠れた依存関係の問題だけではない。Manifest Confusion により、攻撃者は隠れたインストール・スクリプトを含めることも可能になる。これらの隠されたスクリプトや依存関係は、npm CLI によりインストールされるが、npm の Web サイトや大半のセキュリティ・ツールには表示されない」と BleepingComputer に述べている。

残念ながら、npm コミュニティおよび、npm@6/npm@9/yarn@1/pnpm@7 などを含む、すべての主要なパッケージ・マネージャーが、この問題の影響を受けている。

npm@6 executing install script not present in manifest or vice versa
npm@6 executing install script not present in manifest or vice-versa (blog.vlt.sh)


言い換えると、依存関係/バージョン番号/パッケージ名さえも、正確でなはい可能性があるため、npm レジストリの信頼性の欠如につながる。開発者における緩和策は、”package.json” を読み、バージョン番号/インストールされる依存関係/実行されるスクリプトを、自身で判断することになる。

まだ修正されていない問題

Clarke によると、遅くとも 2022年以降において GitHub は、Manifest Confusion の問題を認識していたとされる。それを裏付けているのが、npm CLI の GitHub リポジトリに提出された、”node-canvas” パッケージに関するバグレポートだという。

彼は、2023年3月9日に、この問題の例を示した詳細な HackerOne レポートを提出している。

2023年3月21日に、GitHub はチケットをクローズし、この問題に対処していると回答した。しかし、依然としてリスクが残っているが、そのことは npm コミュニティにも伝えられていない。

Clarke は、npm が大規模であり、この安全が担保されない方式が、何年も続けられていたことから、この問題への対処は些細なことでは済まされないと述べている。

GitHub が、npm における Manifest Confusion に対処する計画を立てるまで、パッケージの作者やメンテナは、マニフェスト・データへの依存を排除し、その代わりに名前とバージョン以外の全てメタデータを、操作されにくい “package.json”ファイルから取得すべきだと、Clarke は提案している。

また、パッケージ・データベースと npm クライアントの間でレジストリ・プロキシを使って、マニフェスト・データとパッケージ tarball 情報の一貫性を保証するための、チェックおよび検証を実装することも、もう1つの保護対策になるだろう。

この問題について、BleepingComputer は GitHub に問い合わせており、返答があり次第、この記事を更新する。

かなり大きな問題になりそうです。とは言え、Darcy Clarke さんの指摘により、多くの開発者が知ることになったので、それは、それで、良かったのかもしれません。すでに、NPM パッケージの不整合をチェックするための、Python ベースのツールがリリースされているようです。このブログでも、この問題を追いかけていく予定です。