knqyf263's blog

自分のためのメモとして残しておくためのブログ。

セキュリティツールの評価は難しい

前から思ってたことをちょっと書かずにいられなくなったのでポエムを書きました。

背景

お前誰だよってなるかもしれないので書いておくと、Trivyという脆弱性スキャナーのメンテナをやっています。

github.com

とある有名な方による以下のツイートがありました。

簡単に言うとTrivyがAlpine Linuxで検知するべき脆弱性を検知していない(false negative)という話です。つまりバグっているという指摘なわけですが、結論から言うと実際には彼の勘違いでTrivyのバグではありませんでした。正直GitHubに来るfalse positive/negativeに関するIssueの9割近くは報告者の勘違いなので(一般論ではなくTrivyの場合です)まずはちゃんと原因を把握しようと思ったのですが、その前にすでにAlpineのセキュリティチームの方が反論してくれていました。

こうやって開発者である自分以外の方が反論してくれるの嬉しいなと思う一方で(元ツイートは言葉が強かったので削除されたようです)、知名度のある方ですらセキュリティツールの評価をするのは難しいなと改めて思ったので、なぜ難しいと思うのかについてまとめます。上のツイートをきっかけに突然思い立って書いてるので何か書き忘れているところがあると思います。その場合は追記します。

問題

一応説明しやすいように自分の開発しているスキャナーを例として使っていますが、ログ解析だったりファイアウォールだったり他のセキュリティツールでも当てはまることは多いと思います。開発者の立場で書いていますが、以下の内容はセキュリティツールを評価する立場の時に役立つかもしれないということで書いています。

あと、評価をより一層難しくしている原因としてDevSecOpsなどが進みセキュリティツールの評価をセキュリティ組織以外が行うケースが増えたこともあるのではないかと考えています。以前は既に経験や知識のあるセキュリティエンジニアが評価を行っていたが、今ではDevやOps側の人間が行うため経験や知識が不足している可能性があると推測しています。

検知している方が正しいように見えがち

これはツールの比較をする時に起こりがちです。実際、脆弱性スキャナーのメンテナを始めてから数え切れない程のツール比較の報告をもらっています。つい先週も別のツールではLog4Shellを検知するのにTrivyは検知しないんだけどバグってんじゃないの?という報告をもらいました。実際にはそのツールの実装がバグっており、"検知しない"が正解でした。それを証明するためにそのツールのデバッグまでしており、何で無償で他のツールのバグ直さないといけないんだ...と思いましたが、ここで重要なのは検知しないツールのほうが間違っているように見られがちということです。

上で紹介したツイートの件も同じです。別のスキャナーでは検知されたため、それを正と信じTrivyの間違いだと思い込みました。"known issues in Alpine images"と、完全に既知のものだと思い込んでいます。検知したスキャナーも検知していないスキャナーも立場は同じはずです。結果が違うのであればどちらが正しいのかを考えるべきなのですが、検知している方が正しく見えてしまうという罠です。

数え切れないほどそういう報告を見てきたのでその一例ではあるのですが、自分は個人的にこの方を以前から色々なOSSのメンテナーをしている人として知っていて、ツイートも見ていたのでそういう人でもこの罠に引っかかるんだなというのはちょっと驚きました。あと自分も詳細を知りたかったのでTwitterでリプライ送ったのですがスルーされて悲しかったです。

Alpineのセキュリティチームもこういう誤った報告に頭を悩ませているようです。自分も毎日そういった報告を受けているので気持ちが痛いほどよく分かります(ECRもTrivyにならないかな...)

もちろん正しい報告もありますし、そういった報告によって改善されてきているのでバグ報告は大歓迎なのですが、一度「本当に検知している方が正しいのだろうか?」という視点を持ってもらえると良いかと思います。

ちなみに間違いは誰にでもあるので、今回の件を批判したいという意図は全く無いです。教訓として

  • やっぱりこの罠には陥りやすいよね
  • バグだと思い込んで公で発信する前に一度立ち止まって確認すると良いよね

という2点があるというだけです。「あれ、これバグかな?」となったらIssueを起票してバグであることを確かめてから発信してもらえると誤解を招かなくて良いなと思います。

条件を揃えるのが難しい

複数スキャナーを比較する際の別の問題として、条件を揃えるのが難しいというのがあります。一例として、スキャナーによってデフォルトのオプションが異なります。例えばとあるスキャナーはCriticalな脆弱性のみデフォルトで表示するかもしれません。一方で他のスキャナーは低い深刻度の脆弱性も全て表示するかもしれません。そうすると、何となく後者のほうがたくさん検知しているため良さそうに見えます。実際には最初のスキャナーもオプションを付けて低い深刻度の脆弱性を表示したら総数は同じになるにもかかわらずです。

Trivyでは上の理由から悩ましい葛藤があります。現在、デフォルトではパッチがない脆弱性であっても表示するようになっています。これは組織によってはパッチがないものでも設定変更やファイアウォールで対応したいかもしれませんし、ゼロデイのような場合はパッチが来る前であっても検知してほしい場合があるためです。ですが、実際にはパッチがなければactionableではないため非表示にしたいという組織が多いです。そういった理由から本当は非表示をデフォルトにしたかったのですが、そうなると表示がデフォルトのスキャナーに比べて検知数が少なく見えます。もちろんちゃんとした人なら分かってくれるのですが、世の中はそこの判断が出来ない人が非常に多いです。誰かが条件を揃えずに総数を比較したブログを公開するとそれに従って使うツールが選ばれます。

この判断は真の意味でユーザに寄り添っていなくて本当に辛いところなのですが、会社として開発している以上は多くの人に使ってもらう必要があり、泣く泣くデフォルト表示の実装になっています。ツールが無名だった頃は血の涙を流しながらやっていましたが、既にある程度知名度を獲得したので将来的には変えたいと思っています。

環境の再現が難しい

複数ツールを比較する時に、そのツールを使った環境を揃えるのが難しい場合があります。例えばネットワークトラフィックに対して異常検知するIDSのようなツールの場合は比較するツールそれぞれに全く同じトラフィックを流さないといけませんが、その量が膨大だったりしたら保存も大変ですし実環境でしか検知されない問題だったら実環境でどう流すのかを考えなければなりません。ネットワーク機器の設定が間違っていて一部のパケットだけうまく一部のツールにだけ転送されていないといったことも起きます。

ホストマシン上で何かしらのセキュリティツールを実行する場合は、そのホストの状態が変わってしまうことで検知結果が変わってしまうこともあります。さっきまでポートが空いていたのに閉じてしまったり、新しくプロセスが立ち上がったり、状態は刻一刻と変化していきます。

同じ環境で検証したつもりが実は微妙に異なっていて、それが異なる結果を生んでいたということはよくあります。

こちらは@m_mizutaniさんのツイートをきっかけに過去の辛さを思い出したので追記しました。

検知数が多い方が良さそうに見える

これは上の話とも関連しますが、検知数が多いほうが良さそうに見えます。この辺は以前も少しブログで触れたのですが、脆弱性検知においては完全に正しく検知できないという状況が存在します。その場合にノイズにならないようにということで検知しないようにするのか、過検知を含むかもしれないけど検知してしまうのか、というのは未だに自分も答えを持っていません。こういったトレードオフは(セキュリティに限らずですが)よく出てきます。

ただし、評価の面から言うと検知数が多いほうがよく見えてしまいます。そうすると例えfalse positveを多く含んだとしても検知数を増やすほうが評価されてしまう問題が起きます。もちろん言い分としてはfalse negativeを減らせるということになります。しかしfalse positveが100件増えてfalse negativeが1件減らせるとなれば正解率(Accuracy)を考えると明らかに好ましくありません。好ましくないというのは自分の主観であってそこの判断は組織がするべきですが、言いたいことはそこまで考えてツールを評価する人は稀ということです。

もちろん1件でも見落として致命的な問題につながったら困るからAccuracyは低くても構わないと考える人もいるかも知れませんが、セキュリティツールが頻繁にアラートをあげてかつそのほとんどが嘘だった場合やがて誰も信じなくなります。そう考えるとオプションとして過検知多めがあっても良いですが、個人的にはデフォルトオプションではアラートは正確であってほしいと思います。そういう判断軸でTrivyは実装しているのですが、数が少なく見えるから多く検知できるように実装してくれという圧を受けることは多いです。

こういったトレードオフに対してツールがどういうアプローチを取っているのか、というのは上の「条件を揃えるのが難しい」とも通ずる話ですが、正しく理解して判断するのは難しいです。

余談ですが、一方でスキャン対象の場合は検知数が少ないほうが正義になりがちです。もちろん少ないほうが良いのですが内訳は考えたほうが良いです。例えば脆弱性スキャンの例で言うとDebianとAlpineの脆弱性数の比較というのがよく行われ、Alpineの方が少ないからAlpineの方が良いと評価されたりします。ですが実際にはDebianの方ではパッチ未提供のものもセキュリティアドバイザリを出していて、Alpineでは出していません。つまりセキュリティアドバイザリの質としてはDebianの方が優れているということになります。にもかかわらずそこまでは踏み込まず単純に数で比較されてしまい、自分の作ったツールによって誤った判断がされているのを悲しい気持ちで見ています。

正解かどうかの判断が難しい

例えば脆弱性が検知された時に、これって検知されるべきなの?という判断はかなり知識が要求されます。そのため他のツールとの比較に走ってしまう気持ちはわかります。例えばRed Hatなどのディストリビューションではbackport fixが存在し、上流の修正バージョンとは異なります。そのためupstreamのバージョンと比較してしまい、自分のバージョンは古いのに検知されない!というバグ報告を受けることは多いです。

また、バージョンを比較するというのも実際には容易ではなくディストリビューションによってロジックが異なります。人間が目で見て判断が難しい場合も存在します。

他にも推移的依存がどう解決されるのか?なども難しいです。例えばAがCの1.0に依存していてBがCの2.0に依存している場合にnpmではバージョンはどう解決されるの?とかまで考えて日頃npmを使っている人は多くないと思います。これはもちろんパッケージマネージャによって実装が異なります。

npm.github.io

もっと言うとテスト用のライブラリの脆弱性は本番にデプロイされないという理由で検知しないようにしてたりするのですが、この辺りも何で検知されないんだと言われることが多いです。

つまり、アラートが出た時にそれが本当に正しいのかを判断することがユーザ側にできないことがあります。その逆も然りでこれは検知されるべきだ!というバグ報告もあります。上で述べたようにDevSecOpsやシフトレフトが進みセキュリティツールを使うのは必ずしもセキュリティに詳しい人間ではないため、この辺は本当に難しいなと思います。

また、この評価の難しさから検知数の大小で比較されてしまう問題に繋がっている気がします。

カバー範囲の正確な見極めが難しい

これまた脆弱性スキャナーの例なのですが、例えばJava対応をしている時に「JARに対応しています」という表面的な文言だけで判断してしまうことがあります。ですが実際にはUber JARには対応してるの?とかShaded JARには対応してるの?とか詳細まで踏み込んで比較する必要があります。しかし、関連技術を深く理解していないとそういった比較は行なえません。

Log4Shellの時に書かれた比較ブログで良い例があるので共有しておきます。これも単純化してしまうと「全てのスキャナーがLog4Shellを検知可能です」ということになります。

www.rezilion.com

@58_158_177_102さんのツイートを見てその辺りを思い出したので追記しました。

検知されないほうが嬉しい

これはツールを比較せずに単体で評価する場合の話ですが、基本的にはみんなセキュリティアラートとか見たくないです。つまり、検知されないと安全だと信じ込んでしまいます。

アラートが出た場合はまだ正当性を確認するためのアクションを起こせますが、アラートが出ない場合は「おや、本当は検知されるべきなのに」と気付くのは非常に難しいです。これもまた正しく評価されていないことになります。検知されてない問題があるかもしれないから正しく評価できてないなと気付けた場合でも、とりあえず比較するかーとなって今度は上の問題に繋がります。

まとめ

セキュリティツールの評価は非常に難しいです。特にこうすると良いという案はなくて難しいよね〜と言ってるだけなのでポエムです。ただ、誤った評価をする前に上のように誤解しやすいポイントを思い出してもらえると違う視点で見ることが出来るかもしれません。

日々「お前のツールバグってるぞ!」と言われ続け「いえ正しいです」と返すのは結構精神的に来るものがあるのですが、その中に改善に繋がるものもあるのでIssue上げるのやめろとか言うつもりはないですしむしろ歓迎です。ただ、「こっちのツールで検知したのにお前のツールバグってるぞ!」と思い込んで主張するよりは「こっちのツールでは検知したけどこれってどっちが正しいの?」みたいなスタンスのほうが嬉しいな〜〜〜〜〜と思ったり思わなかったりです。