TrivyでGridDBリポジトリから脆弱性、シークレット情報、ライセンスのスキャンとSBOMの作成をやってみました！

# はじめに

ライセンススキャンやSBOMの作成において、Trivyに興味を持ち、Qiitaなどで投稿を調べました。多くがコンテナイメージのスキャンとファイルシステムのスキャンに関するものでした。そこで、GitHubのコードリポジトリからスキャンする方法を試み、その手順と結果を備忘録としてまとめました。

# Trivyをインストールする

wget で github から Trivy のパッケージを入手して、dpkg コマンドでインストールします。今回、インストール、使用したバージョンは 0.54.1 です。

```bash
$ wget https://github.com/aquasecurity/trivy/releases/download/v0.54.1/trivy_0.54.1_Linux-64bit.deb
$ sudo dpkg -i trivy_0.54.1_Linux-64bit.deb
$ trivy -v
Version: 0.54.1
・・・
```

詳細については、[Installing Trivy](https://aquasecurity.github.io/trivy/v0.54/getting-started/installation/) をご参照ください。

#  GridDB とは

GridDBとは、IoTやビッグデータに適した、「IoT指向のデータモデル」「高い性能」「高い拡張性」「高い信頼性と可用性」を特長とする、膨大な時系列データを効率よく蓄積し、高い性能をスケーラブルに発揮できるスケールアウト型分散データベースです。
今回、GitHubで公開されている オープンソース版 GridDB である GridDB Comminity Edition の各種スキャンとSBOM作成を行いました。


詳細については、[GridDB](https://www.global.toshiba/jp/products-solutions/ai-iot/griddb.html) をご参照ください。
OSS公開先：https://github.com/griddb/griddb

# コードリポジトリを指定した Trivy の実行

Trivyは以下の構文で実行されます。'repository'には'repo'というエイリアスが存在します。
`$ trivy repository [flags] (REPO_PATH | REPO_URL)` 

以下はリモートの git リポジトリを指定する例です。
`$ trivy repo https://github.com/knqyf263/trivy-ci-test`
以下はローカルの git リポジトリを指定する例です。
`$ trivy repo ~/src/github.com/aquasecurity/trivy-ci-test`

リポジトリのブランチやタグを指定する場合、以下のような構文となります。
`$ trivy repo --branch <branch-name> <repo-name>`
`$ trivy repo --tag <tag-name> <repo-name>`

# 脆弱性スキャン

まずは、脆弱性とシークレット情報のスキャンを試します。
--scanners を省略すると脆弱性とシークレット情報のスキャンが実行されるため、省略しました。

```bash
$ trivy repo https://github.com/griddb/griddb
2024-08-15T12:06:26+09:00       INFO    [vuln] Vulnerability scanning is enabled
2024-08-15T12:06:26+09:00       INFO    [secret] Secret scanning is enabled
2024-08-15T12:06:26+09:00       INFO    [secret] If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2024-08-15T12:06:26+09:00       INFO    [secret] Please see also https://aquasecurity.github.io/trivy/v0.54/docs/scanner/secret#recommendation for faster secret detection
Enumerating objects: 5799, done.
Counting objects: 100% (5799/5799), done.
Compressing objects: 100% (3625/3625), done.
Total 5799 (delta 2664), reused 4995 (delta 1945), pack-reused 0 (from 0)
2024-08-15T12:06:39+09:00       INFO    Number of language-specific files       num=1
2024-08-15T12:06:39+09:00       INFO    [pom] Detecting vulnerabilities...
$
```

スキャンの結果、何も表示されなかったので、脆弱性は検出されなかったようです。

コードリポジトリを指定した際、本当に脆弱性スキャンが行われているか気になったので、インメモリDBの Redis の脆弱性とシークレット情報のスキャンを試しました。こちらは脆弱性情報が表示されました。

```bash
~$ trivy repo https://github.com/redis/redis --timeout 120m
<<< 省略 >>>
utils/req-res-validator/requirements.txt (pip)

Total: 2 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 0, CRITICAL: 0)

┌─────────┬────────────────┬──────────┬────────┬───────────────────┬─────────────────────┬─────────────────────────────────────────────┐
│ Library │ Vulnerability  │ Severity │ Status │ Installed Version │    Fixed Version    │                    Title                    │
├─────────┼────────────────┼──────────┼────────┼───────────────────┼─────────────────────┼─────────────────────────────────────────────┤
│ redis   │ CVE-2023-28859 │ MEDIUM   │ fixed  │ 4.5.1             │ 4.5.4, 4.4.4        │ redis: Async command information disclosure │
│         │                │          │        │                   │                     │ https://avd.aquasec.com/nvd/cve-2023-28859  │
│         ├────────────────┼──────────┤        │                   ├─────────────────────┼─────────────────────────────────────────────┤
│         │ CVE-2023-28858 │ LOW      │        │                   │ 4.4.3, 4.5.3, 4.3.6 │ redis: Async command information disclosure │
│         │                │          │        │                   │                     │ https://avd.aquasec.com/nvd/cve-2023-28858  │
└─────────┴────────────────┴──────────┴────────┴───────────────────┴─────────────────────┴─────────────────────────────────────────────┘
```

# ライセンススキャン

次に、ライセンスのスキャンを試します。--scanners フラグで license を指定します。
以下のようにライセンス情報が出力されます。
ドキュメントには「デフォルトでは、Trivyはapk、apt-get、dnf、npm、pip、gemなどでインストールされたパッケージのライセンスをスキャンします。」と記述されていますので、脆弱性と同様に、ターゲットがコードリポジトリであっても、依存関係を示したロックファイルに依存すると思われます。

```bash
$ trivy repo --scanners license https://github.com/griddb/griddb
2024-08-15T12:08:03+09:00       INFO    [license] License scanning is enabled
Enumerating objects: 5799, done.
Counting objects: 100% (5799/5799), done.
Compressing objects: 100% (3625/3625), done.
Total 5799 (delta 2664), reused 4995 (delta 1945), pack-reused 0 (from 0)
 
java_client/pom.xml (license)
 
Total: 3 (UNKNOWN: 2, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
 
┌─────────────────────────────┬─────────────┬────────────────┬──────────┐
│           Package           │   License   │ Classification │ Severity │
├─────────────────────────────┼─────────────┼────────────────┼──────────┤
│ com.github.griddb:gridstore │ Apache-2.0  │ Notice         │ LOW      │
├─────────────────────────────┼─────────────┼────────────────┼──────────┤
│ org.slf4j:slf4j-jdk14       │ MIT License │ Non Standard   │ UNKNOWN  │
├─────────────────────────────┤             │                │          │
│ org.slf4j:slf4j-api         │             │                │          │
└─────────────────────────────┴─────────────┴────────────────┴──────────┘
```

拡張ライセンススキャンを有効にするには、--license-full を使用します。パッケージのライセンスに加えて、Trivyはソースコードファイル、Markdownドキュメント、テキストファイル、およびLICENSEドキュメントをスキャンしてライセンス使用状況を特定します。
--license-full を追加して実行すると、上記結果に加えて以下の情報が出力されます。（一部省略）

```bash
$ trivy repo --scanners license --license-full https://github.com/griddb/griddb
<<< 省略 >>>
Loose File License(s) (license)

Total: 596 (UNKNOWN: 197, LOW: 195, MEDIUM: 0, HIGH: 22, CRITICAL: 182)

┌────────────────┬──────────┬─────────────────────────────────┬──────────────────────────────────────────────────────────────┐
│ Classification │ Severity │             License             │                        File Location                         │
├────────────────┼──────────┼─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ Forbidden      │ CRITICAL │ AGPL-3.0                        │ 3rd_party/sqlite_mod/gs_ext/maings.c                         │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
│                │          │                                 │ 3rd_party/sqlite_mod/gs_ext/memgs.c                          │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
│                │          │                                 │ GNU-AGPL-3.0.txt                                             │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
│                │          │                                 │ LICENSE                                                      │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
│                │          │                                 │ server/affinity_manager.h                                    │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
├────────────────┼──────────┼─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ Restricted     │ HIGH     │ GPL-2.0                         │ 3rd_party/sqlite_mod/autoconf/ltmain.sh                      │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ GPL-2.0-with-autoconf-exception │ 3rd_party/zstd/tests/gzip/test-driver.sh                     │
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ GPL-3.0                         │ 3rd_party/zstd/tests/gzip/gzip-env.sh                        │
<<< 省略 >>>
├────────────────┼──────────┼─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ Notice         │ LOW      │ Apache-2.0                      │ 3rd_party/Apache_License-2.0.txt                             │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ BSD-2-Clause                    │ 3rd_party/fletcher32_simd/fletcher32_simd/LICENSE            │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ BSD-3-Clause                    │ 3rd_party/BSD_License.txt                                    │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ MIT                             │ 3rd_party/MIT_License.txt                                    │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
│                │          ├─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│                │          │ Zlib                            │ 3rd_party/zstd/zlibWrapper/examples/example.c                │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
├────────────────┼──────────┼─────────────────────────────────┼──────────────────────────────────────────────────────────────┤
│ Non Standard   │ UNKNOWN  │ blessing                        │ 3rd_party/sqlite_mod/ext/async/sqlite3async.c                │
│                │          │                                 ├──────────────────────────────────────────────────────────────┤
<<< 省略 >>>
└────────────────┴──────────┴─────────────────────────────────┴──────────────────────────────────────────────────────────────┘
```

# SBOM作成

次に、SBOMの作成を試します。今回は SPDX形式で出力しました。

```bash
$ trivy repo --format spdx-json --output sbom-spdx.json https://github.com/griddb/griddb --timeout 120m
2024-08-17T10:31:51+09:00       INFO    "--format spdx-json" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the "spdx-json" report.
Enumerating objects: 5799, done.
Counting objects: 100% (5799/5799), done.
Compressing objects: 100% (3627/3627), done.
Total 5799 (delta 2663), reused 4995 (delta 1943), pack-reused 0 (from 0)
2024-08-17T10:32:05+09:00       INFO    Number of language-specific files       num=1
```

以下は作成された SPDX 形式の SBOM ファイルです。

```json
{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "https://github.com/griddb/griddb",
  "documentNamespace": "http://aquasecurity.github.io/trivy/repository/github.com/griddb/griddb-b29a4477-c5e5-4916-8e77-193c1ff12d7a",
  "creationInfo": {
    "creators": [
      "Organization: aquasecurity",
      "Tool: trivy-0.54.1"
    ],
    "created": "2024-08-17T01:32:05Z"
  },
  "packages": [
    {
      "name": "java_client/pom.xml",
      "SPDXID": "SPDXRef-Application-16c611e3fd3e1f1e",
      "downloadLocation": "git+https://github.com/griddb/griddb",
      "filesAnalyzed": false,
      "attributionTexts": [
        "Class: lang-pkgs",
        "Type: pom"
      ],
      "primaryPackagePurpose": "APPLICATION"
    },
    {
      "name": "com.github.griddb:gridstore",
      "SPDXID": "SPDXRef-Package-8d3216299147da98",
      "versionInfo": "5.6.0",
      "supplier": "NOASSERTION",
      "downloadLocation": "git+https://github.com/griddb/griddb",
      "filesAnalyzed": false,
      "sourceInfo": "package found in: java_client/pom.xml",
      "licenseConcluded": "Apache-2.0",
      "licenseDeclared": "Apache-2.0",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:maven/com.github.griddb/gridstore@5.6.0"
        }
      ],
      "attributionTexts": [
        "PkgID: com.github.griddb:gridstore:5.6.0",
        "PkgType: pom"
      ],
      "primaryPackagePurpose": "LIBRARY"
    },
    {
      "name": "org.slf4j:slf4j-api",
      "SPDXID": "SPDXRef-Package-8152e8575782b4cc",
      "versionInfo": "1.7.7",
      "supplier": "NOASSERTION",
      "downloadLocation": "git+https://github.com/griddb/griddb",
      "filesAnalyzed": false,
      "sourceInfo": "package found in: java_client/pom.xml",
      "licenseConcluded": "MIT-License",
      "licenseDeclared": "MIT-License",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:maven/org.slf4j/slf4j-api@1.7.7"
        }
      ],
      "attributionTexts": [
        "PkgID: org.slf4j:slf4j-api:1.7.7",
        "PkgType: pom"
      ],
      "primaryPackagePurpose": "LIBRARY"
    },
    {
      "name": "org.slf4j:slf4j-jdk14",
      "SPDXID": "SPDXRef-Package-dedd1d1caa8a4393",
      "versionInfo": "1.7.7",
      "supplier": "NOASSERTION",
      "downloadLocation": "git+https://github.com/griddb/griddb",
      "filesAnalyzed": false,
      "sourceInfo": "package found in: java_client/pom.xml",
      "licenseConcluded": "MIT-License",
      "licenseDeclared": "MIT-License",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:maven/org.slf4j/slf4j-jdk14@1.7.7"
        }
      ],
      "attributionTexts": [
        "PkgID: org.slf4j:slf4j-jdk14:1.7.7",
        "PkgType: pom"
      ],
      "primaryPackagePurpose": "LIBRARY"
    },
    {
      "name": "https://github.com/griddb/griddb",
      "SPDXID": "SPDXRef-Repository-9cb0e66f95f0ff17",
      "downloadLocation": "git+https://github.com/griddb/griddb",
      "filesAnalyzed": false,
      "attributionTexts": [
        "SchemaVersion: 2"
      ],
      "primaryPackagePurpose": "SOURCE"
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-Application-16c611e3fd3e1f1e",
      "relatedSpdxElement": "SPDXRef-Package-8d3216299147da98",
      "relationshipType": "CONTAINS"
    },
    {
      "spdxElementId": "SPDXRef-DOCUMENT",
      "relatedSpdxElement": "SPDXRef-Repository-9cb0e66f95f0ff17",
      "relationshipType": "DESCRIBES"
    },
    {
      "spdxElementId": "SPDXRef-Package-8d3216299147da98",
      "relatedSpdxElement": "SPDXRef-Package-dedd1d1caa8a4393",
      "relationshipType": "DEPENDS_ON"
    },
    {
      "spdxElementId": "SPDXRef-Package-dedd1d1caa8a4393",
      "relatedSpdxElement": "SPDXRef-Package-8152e8575782b4cc",
      "relationshipType": "DEPENDS_ON"
    },
    {
      "spdxElementId": "SPDXRef-Repository-9cb0e66f95f0ff17",
      "relatedSpdxElement": "SPDXRef-Application-16c611e3fd3e1f1e",
      "relationshipType": "CONTAINS"
    }
  ]
}
```

# まとめ

Trivyを使用してコードリポジトリから情報を収集し、脆弱性スキャン、ライセンススキャン、およびSBOMの作成を簡単に行うことができることを確認しました。コードリポジトリを参照しているからといってソースコード解析を行っているのではなく、依存関係を示した package-lock.json, yarn.lock などのロックファイルが必要です。また、trivy-db で作成されている脆弱性DBを参照していますので、脆弱性スキャンはこの情報がポイントです。

もし、記述について誤りがあったり、気になることがあれば、編集リクエストやコメントでフィードバックしていただけると助かります。