フューチャー技術ブログ

俺のシステムがこんなに脆弱性だらけのわけがない(linkedpackageの紹介)

セキュリティに対して、きちんとお金をかけて対応すべきである、というのが近年の風潮です。そんな中、システム開発では多くのオープンソースのコンポーネントを組み合わせてシステムを構築するようになってきたため、使っている部品の脆弱性管理、というのがかなり大きな市場になってきました。

当社にはOSSのVulsと、それに脆弱性管理の手間を減らしてくれるFutureVulsというSaaSサービスがあります。コンテナのスキャンだとAqua SecurityのTrivyが有名ですね。

開発中のアプリケーションのスキャナーというと、Node.jsのnpmコマンドが脆弱なパッケージの検知機能(auditサブコマンド)を内蔵していますし、Goも公式脆弱性管理データベースのページを作り、新しい仕組みを構築しようとしています(ドキュメント準標準のチェックコマンド)。言語をまたいで使えるものにはsnykもありますね。

フォールスポジティブ(偽陽性)を減らす

Node.jsでの開発は4桁ぐらいパッケージに依存することがありえます。npm auditで少しでも古いパッケージを使うと大量の脆弱性が報告されることがあります。でも、よくよく見てみると実は関係ないのかな? とも思えるような脆弱性もたくさん出てきますが、なかなか判定を1つ1つ行うのは大変です。

ですが、アプリケーションの開発でいうと、「パッケージリストには追加してみたのだけど、実際には使っていないパッケージ」などがあったりします。Goだとgo mod tidyでお掃除してくれますが。あとは開発用に追加したもので、本番コードにはリンクされていないものもあります。Node.jsなんかは、ほとんどはそうなんじゃないですかね。

あとは、脆弱性がヒットしたとしても、そのパッケージ中の一部の機能は使っているが該当する機能は使っていない、ということもあります。そのため、実際にビルドしたアプリケーションに含まれるソースコードでフィルタリングしたらいいんじゃないか、と思って実証実験的に作ったパッケージが次のものです。

https://github.com/future-architect/linkedpackage

神戸さんからメッセージもらうまでは、作ったことをすっかり忘れていて、とりあえず公開だけしたのが上のリポジトリです。ライセンスはひとまずVulsにあわせてGPLにしています。とりあえず公開だけしたのでREADMEもないですが

処理の方法

現時点ではJavaScriptのプロジェクトに限定した機能になっています。ソースマップをざっとスキャンして、実行ファイルに含まれるソース片を提供しているパッケージを取り出します。コマンドとしても動かせるようにしてあり、linkedpackage auditコマンドを使うと、npm auditの結果を、利用パッケージに限定してフィルタリングして表示、みたいなことができます。

ソースマップ中のパス表記は、その中で識別子が認識一致していたら問題はないと思うのですが、実際のソースコードとリンクさせるには逆変換が必要かなと思っています。ツールによって出てくるパス表記がいろいろあるので、これを地道に拾ってモジュール名を拾うようにしています。地道さが必要ですね。

  • webpack:///./node_modules/@babel/runtime/helpers/wrapNativeSuper/_index.mjs
  • ../webpack:/ncc-project/node_modules/trim/index.js
  • webpack://_N_E/ignored|/prj/node_modules/next/dist/shared/lib/router|./utils/resolve-rewrites

今後

Goもdebugパッケージ使えば実行ファイルから、利用しているモジュール一覧が取れるので行けそうですね。そのうち作ろうかな。

ただ、実行ファイルに入っているからといって、それがまた実行されるわけではない、というのはあります。JavaScriptだとtree shakingという最適化がありますが完璧にフィルタリングできるわけではありません。Goはそこまで積極的なCode Eliminationはしてない印象がありますし、グローバル変数を含めinit()から参照されるオブジェクトなんかは使ってなくてもリンクされてしまいます。Goは1.20からプロファイラ機能とリンクしたオプティマイザが入ります。この情報が外部のツールから使えるかどうかはわからないですが、実際に実行されている行だけ取り出せれば、また精度の高いフィルタリングができるんじゃないかな、と思っています。