【入門】知ると差がつく、OSSセキュリティ脆弱性のスキャン・管理ツール概説

こんにちは。株式会社 日立ソリューションズの森下です。
この記事は、日立グループ OSS Advent Calendar 2019 の16日目の記事になります。

# はじめに

近年、OSS（Open Source Software、オープンソースソフトウェア）が個人や企業問わずさまざまな場面で利用されていますが、利用の拡大とともにOSSのリスク管理、主にOSSのセキュリティ脆弱性の継続管理の必要性が叫ばれています。
最近の事例では、2017年に米国のEquifaxがApache Strutsの脆弱性をつかれ1億4300万人分の大規模な情報流出を起こしました。Strutsに関しては日本も例外ではなく、同様に[多くの被害が出たこと](https://piyolog.hatenadiary.jp/entry/20170311/1489253880)は記憶に新しいかと思います。また2018年にはnpmパッケージ「eventstream（flatmap-stream）」に攻撃コードが仕込まれる等、OSSライブラリへのサプライチェーン攻撃と思われる動きも見られるようになってきました。

このような流れを受け、OSSをセキュリティの観点で適切に管理しようという風潮も高まり、さまざまなスキャン・管理ツールが登場してきました。例えば、日本国内でも知られているツールとしては以下が挙げられます。

- BlackDuck  
  https://www.synopsys.com/ja-jp/software-integrity/security-testing/software-composition-analysis.html
- Clair  
  https://github.com/quay/clair
- FOSSID  
  https://fossid.com/
- Trivy  
  https://github.com/aquasecurity/trivy
- Vuls, FutureVuls  
  https://github.com/future-architect/vuls , https://vuls.biz/
- WhiteSource  
  https://www.whitesourcesoftware.com/
- FOSSA  
  https://fossa.com/

他にも、CNCFのCloud Native Interactive Landscape 等を見れば、関連するツール/プロバイダーを確認することができます。
CNCF Cloud Native Interactive Landscape (Security&Compliance)：https://landscape.cncf.io/category=security-compliance&format=card-mode&grouping=category

今回は、OSS脆弱性管理を検討されている方々に向けて、ツールの一般的な仕様およびツールを見る際（主に選定時）のポイントとなる観点について解説を行います。
ある程度ツールの仕組みを把握していることによって、自分/自社がどのようなツールを選択すれば良いのかが分かってくると思います。本記事は概要説明になりますので、ほとんど知識がないという方にも是非参考にしていただければと思います。

# この記事でお伝えすること

- OSS脆弱性スキャン・管理ツールは一般的にどのような仕組みなのか
- 仕組みから考えた場合、ツール選択のポイントはどこになるのか

# 想定読者

- OSS脆弱性を管理しようと考え始めた方
- さまざまなツールの中で何を使えば良いか分からない方
- ソフトウェア開発に関するセキュリティを考えているすべての方

# 用語の説明

念のため記事中に出てくる用語の説明を事前にしておきます。

- [CVE (Common Vulnerabilities and Exposures)](https://cve.mitre.org/)  
  共通脆弱性識別子。米国政府の支援を受けた非営利団体のMITRE社が採番している識別子です。
- [NVD (National Vulnerability Database)](https://nvd.nist.gov/)  
  米国立標準技術研究所（NIST）の脆弱性データベースです。

# OSS脆弱性スキャン・管理ツールの一般的な仕様

それではまず、OSS脆弱性スキャン・管理ツールの一般的な仕組みについて説明していきます。さまざまなツールが世の中にあり、それぞれ細かい機能の違いは存在しますが、基本的な部分はほとんど同じような仕組みで動いていると考えて差し支えありません。

## 大枠の構成

大枠としては以下のとおり、大きく「検出部」「DB部」の2つで構成されている、と考えておくと良いと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328366/77187bf0-df7d-4c16-ddb4-9130c29da539.png)
検出部は、スキャン対象から識別情報（key情報）を抜き出します。このkeyを使って、DBから脆弱性の情報を取得してUIに表示します。これが基本的なOSS脆弱性スキャンの流れです。
ではそれぞれ見ていきましょう。

## 検出部

「検出部」と名付けたこの部分の役割は「スキャン対象から識別情報（key情報）を取得すること」になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328366/692e356c-90ba-acc0-59b9-08d28176b0d3.png)
スキャンの対象はソースコード（リポジトリ）や実行バイナリ、パッケージ、コンテナ、もしくはサーバOSの場合もありますが、これらを対象として、まずはOSS脆弱性を導くためのkey情報を取得します。
key情報としては、具体的には「脆弱性ID」「パッケージID」「ファイルハッシュ値」などが該当します。
例として、Node.js（npm）のプロジェクトをスキャン対象とした場合にどのようにkey情報を検出できるか考えてみましょう。

npmプロジェクトであれば、`npm audit`によってプロジェクトが利用しているOSSの脆弱性情報が得られます。この結果をパースすれば、CVE番号やadvisory番号（脆弱性ID）が得られます。

```
$ npm audit --json
{
  "advisories": {
    "1065": {                  <---   ★ここ！★
      "findings": [
        {
          "version": "4.17.11",
          "paths": [
            "async>lodash"
          ]
        }
      ],
      "id": 1065,
      "module_name": "lodash",
      "cves": [
        "CVE-2019-10744"        <---   ★ここ！★
      ],

（一部省略しています。）
```

また、同様にプロジェクトのディレクトリに存在する`package-lock.json`にはプロジェクトが利用するOSSライブラリのnameおよびversionが記載されていますので、この結果をパースすればパッケージIDが取得できます。

```
$ cat package-lock.json
{
  "name": "sample",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "lodash": {                    <---   ★ここ！★
      "version": "4.17.11",        <---   ★ここ！★
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
    }

(一部省略しています。)
```

また、実際に利用されるOSSライブラリの実体はnpmプロジェクトのnode_modulesディレクトリに格納されるので、この中のファイルに対して何等かのルールでハッシュ値を生成すれば、key情報としてファイルハッシュを得ることができます。

```
$ ls node_modules
async    lodash
$ create_hash.sh node_modules/lodash
du402ntgfd9kg......        <---   ★これ！★
```

## DB部

では続いて、得られたkey情報を使ってDBから脆弱性情報を抜き取る段階です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328366/929188a6-4d60-31bb-01fc-5064fdd9b975.png)
こちらは、DB部のイメージ画像です（あくまで説明のためのイメージとなります）。DBの中身は用いられるkey情報によって変わってきますが、概ね脆弱性の情報としてNVDの情報は持っており、これとkey情報を紐づけるデータべースが整備されています（スキャン前段階で構築、もしくはクラウド上に配備されます）。このデータを使って、スキャンツールは検出部が取得したkey情報と既知の脆弱性情報を紐づけ、最終的にスキャン対象が含んでいるOSS脆弱性を報告してくれるという仕組みになっています。

# 仕様から考える、OSS脆弱性スキャン・管理ツールで見るべきポイント

以上がツールの基本的な仕様になります。これらを踏まえて、ツールを評価/選定する際のポイントを書いていきます。

## スキャン対象の幅と精度

OSS脆弱性に限らず、あらゆるスキャンツールに対して言えることですが、

- スキャン対象としてどんなものを扱えるのか
- スキャンの精度はどれくらいか

については、まずチェックしておく必要があります。

### スキャン可能なプログラミング言語（パッケージマネージャ）やOSのディストリビューションの範囲はどこまでか

何をスキャン対象にできるかは重要なポイントの一つです。ソースコードなのか、実行バイナリなのか、パッケージなのか、コンテナなのか、サーバなのか。また、プログラミング言語はどこまで対応か、パッケージマネージャはどこまで対応か、などです。もちろん、より多くのものをスキャンできた方が嬉しいわけですが、いくら対応範囲が広くても検出の精度が低いのでは問題です。場合によっては、より適したツールを複数使い分けるという選択もあるでしょう。自身が開発しているソフトウェアが組み込み系なのか、WEB系なのかによっても選択肢は変わってきますので、自身の開発内容と合わせて考えるのがポイントになります。

### 検出部のパース精度、DB内データとのマッチング時の精度はいかほどか

ツールの最終的なスキャン結果では脆弱性情報のみが表示されますが、裏では脆弱性IDやパッケージIDなど、key情報となる中間データが吐かれている場合が多いです。これを基に、どこまでスキャンできていたのかを把握できる場合があります。
ツールの表面的な結果だけを見れば「脆弱性がほとんど検出できなかった」と思われるスキャン結果だったとしても、中間データを見ればわずかな誤差だったと判断できる場合があります（そしてこの場合はわずかな修正で性能が上がることもあり得ます）。仕組みを理解した上で「これはなぜ精度が悪かったのか、これはなぜ検知できなかったのか」などと考えることができれば、数回のスキャンサンプルを基にした正解率の評価よりも、本質的な精度評価ができるようになるでしょう。

## 脆弱性DBの量と質

OSS脆弱性のスキャンでもう一つ肝になるのはDBの量と質です。仕組みの説明をしたのでお分かりいただけると思いますが、そもそもDB部にデータとして存在しない脆弱性はスキャンで検知できません。より多く、より早く脆弱性を収集し、かつ、より有益な情報を持っているDB部であるかどうかは確認すべきポイントです。

### NVD以外の脆弱性DBが情報源としてどれだけ使われているか

世の中のすべての脆弱性がCVE番号をもってNVDに載るわけではありません。CVEとして採番されない脆弱性は、当たり前ですがNVDにはいつまでも載ることはありません。
世の中にはNVDの他にも「Security Advisories」等の名前で脆弱性情報が公開されています。例えばnpmパッケージのSecurity Advisoriesはこちらです。https://www.npmjs.com/advisories

また"VulnDB"のような、CVE以外の情報も持っている有償の脆弱性DBも存在します（ https://vulndb.cyberriskanalytics.com/ ）。これらのDBはNVDよりも脆弱性情報が上がってくるのが早いと言われます。こういった特徴からしても、DB部の情報源が何なのかをしっかりとチェックする必要があります。

### さらに+αの情報をどれだけ持っているか

実際の脆弱性対策の現場では、検知された脆弱性に対して「どれくらい危険なのか」「どれくらい影響があるのか」「どう対処したら良いのか」等を検討する必要があり、ここが最も負荷がかかるポイントであると言われます。これに対して、より実用的な回避・緩和・修正のガイダンスを持っているかどうかは確認すべきポイントになるでしょう。
ツールによっては専任のセキュリティチームが情報を別途整備していたり、また他ツールではWEBクローリングで得た周辺情報（WEB上での攻撃コードの公開有無など）を基にさらなるリスク定義情報を整備していたりします。このレベルは無償ツールでは厳しいですが、実運用を考えると検討すべきポイントになるでしょう。

## その他

他にも以下のようなポイントも確認すべき点として挙げられます。

- 新たな脆弱性が検知された際の通知機能はあるか/どれだけ柔軟か
- 検出された脆弱性のトリアージ機能はあるか
- スキャンやDB構築時の処理速度はいかほどか
- CI/CDプラットフォームと連携が可能か
- 各種社内システムとの連携が可能か

これら、さまざまな観点で検討することが重要になってきます。

# 最後に

以上がOSS脆弱性スキャン・管理ツールの解説、およびツール選択時の評価ポイントになります。少々長くなりましたが、今後の皆様のお役に立てれば幸いです。