🎃

PCにインストールしたすべてのnode packages情報を取得する

に公開

マルウェアnpmがインストールされていることを調べたい

近年流行しているnpmサプライチェーン攻撃ですが、アップデートやlatestのインストール時に悪意のあるスクリプトが実行されてしまうため、GitHub上でのSBOM(Software Bill of Materials)を利用した解析では不十分です。

実際の端末でnpmパッケージがインストールされた形跡を調査するには実際にインストールされているパスを調査することも必要になる場合があります。
しかしすべてのプロジェクトにあるnode_modulesを調査するとなると非常に時間がかかり現実的でないです。

パッケージマネージャーのキャッシュを調査して効率的に収集する

最近のパッケージマネージャーはcacheを利用してパッケージの重複時に高速化を図っています。
実際にインストールされたパッケージの情報は一元的に管理されていることが多く以下は代表的な例です。

Package Manager Cache Locations
npm ~/.npm, global node_modules
ppm ~/.pnpm-store, ~/.local/share/pnpm/store
yarn ~/.yarn-cache, ~/.cache/yarn (Yarn v1)
bun ~/.bun/install/cache
deno ~/.cache/deno/npm, $DENO_DIR

~/.npm以下でnode_modulesを探すと_npxやグローバルインストールされたパッケージを含めたすべてのパッケージ情報を取得できます。

find ~/.npm -type d -name "node_modules" -exec find {} -type f -name "package.json" \;

osqueryで一括取得する

これをパッケージマネージャーごとに実行することは大変なので端末の情報をsqlで記述して取得するosqueryを利用して管理を統一化します。
osqueryはクロスプラットフォームで動作し、SQLという共通の形式で拡張できるため、go packagesやrust cratesなど他のパッケージマネージャーにも応用が可能なのが嬉しい点です。

https://github.com/osquery/osquery

https://github.com/osquery/osquery

osqueryはextensionの形で拡張が可能なため、今回はnode packages用のextensionを作成しました。builtinなテーブルもありますが、ちょっと物足りなかったので独自実装です。

osquery

https://github.com/HikaruEgashira/node-packages-osquery-extension

# extensionをインストール(FROM node_packagesが使えるように)
mise use -g github:HikaruEgashira/node-packages-osquery-extension

# osqueryiでインタラクティブに実行。extensionを読み込む
osqueryi --extension $(which node_packages_extension)
osquery> SELECT name, version, manager FROM node_packages LIMIT 10;
+-----------------------------------+---------+---------+
| name                              | version | manager |
+-----------------------------------+---------+---------+
| @aashutoshrathi/word-wrap         | 1.2.6   | bun     |
| @alloc/quick-lru                  | 5.2.0   | bun     |
| @babel/code-frame                 | 7.27.1  | bun     |
| @babel/compat-data                | 7.28.5  | bun     |
| @babel/core                       | 7.28.5  | bun     |
| @babel/generator                  | 7.28.5  | bun     |
| @babel/helper-compilation-targets | 7.27.2  | bun     |
| @babel/helper-globals             | 7.28.0  | bun     |
| @babel/helper-module-imports      | 7.27.1  | bun     |
| @babel/helper-module-transforms   | 7.28.3  | bun     |
+-----------------------------------+---------+---------+

これでnpm, ppm, yarn, bun, denoでインストールされたすべてのパッケージ情報を一括で取得できます。

これでnpmサプライチェーン攻撃は対策できている?

npmがサプライチェーンとして悪用されやすい理由としてnpxのようなデフォルトで最新版をインストールする仕組みや、インストール時にスクリプトを実行できるためインストールするだけで侵害できるといった構造的な問題が根本にあります。
ここでやれるのはIOC収集(被害の痕跡を保存すること)のみで、すでに侵害されていることには変わりありません。
また、npmサプライチェーンは端末を狙ったものだけではなくGitHub Actions RunnerのようなCI/CD環境を狙ったものもあり、1方面を調査しただけでは不十分です。

https://github.blog/security/supply-chain-security/our-plan-for-a-more-secure-npm-supply-chain/

まずはnpmパッケージを利用する上での適切な対策を行って、その上で侵害時の対応を素早くするためにこのような知識/ツールを活用するといった目的で利用してみてください。

https://zenn.dev/azu/articles/ad168118524135

スターお待ちしてます!

https://github.com/HikaruEgashira/node-packages-osquery-extension


  • yarn v2以降はPlug'n'Playを採用しており、一元管理をしていないため、端末全体の走査が必要です。

Discussion