Docker ローカルイメージに対するぜい弱性スキャン

読む時間の目安: 10 分

開発サイクルを早めたいと思いませんか? CVE をすばやく検出して修復する方法としてdocker scan IMAGE_NAMEを実行してください。 詳しくは イメージのスキャン方法 を確認してください。

Docker のローカルイメージに対するぜい弱性スキャンは、開発者および開発チームにおいてコンテナーイメージのセキュリティ状況を明らかにするものであり、スキャン中に発覚した問題への対処につながります。 結果としてより安全なデプロイを実現するものです。 Docker スキャンは Snyk エンジンを使って動作します。 ローカルの Dockerfile やローカルイメージに対して、セキュリティ状況を可視化して示します。

ぜい弱性スキャンは CLI から起動し、CLI を使ってスキャン結果を確認します。 スキャン結果は、ぜい弱性情報データベース CVE(Common Vulnerabilities and Exposures)の一覧として構成され、そこにはぜい弱性の発生源、つまり OS パッケージやライブラリなど、またぜい弱性が発生したバージョン、CVE によって検出された問題を修復するための推奨される修正バージョン(入手可能である場合)が示されます。

Log4j 2 CVE-2021-44228

docker scanのバージョンがv0.11.0よりも古い場合、Log4j 2 CVE-2021-44228 を検出することができません。 この問題を解決するためには Docker Desktop のバージョンが 4.3.1 またはそれ以降のものをインストールする必要があります。 詳しくは Log4j 2 CVE に対するイメージスキャン を参照してください。

ぜい弱性スキャンの実行に必要となるシステム要件については 前提条件 を参照してください。

本ページでは CLI コマンドdocker scanの情報を示します。 Docker Hub を通じて Docker イメージを自動スキャンする情報に関しては Docker Hub のぜい弱性スキャン を参照してください。

Log4j 2 CVE に対するイメージスキャン

Docker スキャンのバージョンがv0.11.0よりも古い場合、イメージのぜい弱性スキャンを行っても Log4j 2 CVE-2021-44228 を検出することができません。 この問題を解決するには Docker の最新版をインストールする必要があります。

Docker Desktop に含まれているdocker scanプラグインを利用している場合は、Docker Desktop のバージョンを 4.3.1 またはそれ以降にアップデートしてください。 ダウンロードに関しては、Mac のリリースノート、あるいは Windows のリリースノートを参照してください。

Linux を利用している場合は、以下のコマンドを手作業により実行して、最新のdocker scanをインストールします。

Ubuntu や Debian のような.debをベースとするディストリビューションでは、以下のようにします。

$ apt-get update && apt-get install docker-scan-plugin

CentOS や Fedora のような rpm ベースのディストリビューションでは、以下のようにします。

$ yum install docker-scan-plugin

上とは別にdocker scanのバイナリは、GitHub レジストリ Docker Scan やプラグインディレクトリ内の install からダウンロードすることができます。

docker scanのバージョン確認

docker scanのアップグレードを行ったら、インストールしたdocker scanが最新であるかどうかを、以下のコマンドを実行して確認します。

$ docker scan --accept-license --version
Version:    v0.12.0
Git commit: 1074dd0
Provider:   Snyk (1.790.0 (standalone))

If your code output contains ORGAPACHELOGGINGLOG4J, it is likely that your code is affected by the Log4j 2 CVE-2021-44228 vulnerability. When you run the updated version of docker scan, you should also see a message in the output log similar to:

Upgrade org.apache.logging.log4j:log4j-core@2.14.0 to org.apache.logging.log4j:log4j-core@2.15.0 to fix
✗ Arbitrary Code Execution (new) [Critical Severity][https://snyk.io/vuln/SNYK-JAVA-ORGAPACHELOGGINGLOG4J-2314720] in org.apache.logging.log4j:log4j-core@2.14.0
introduced by org.apache.logging.log4j:log4j-core@2.14.0

For more information, read our blog post Apache Log4j 2 CVE-2021-44228.

イメージのスキャン方法

docker scanコマンドは、イメージ名またはイメージ ID を指定して、既存の Docker イメージをスキャンします。 たとえば以下のコマンドは hello-world イメージをスキャンします。

$ docker scan hello-world

Testing hello-world...

Organization:      docker-desktop-test
Package manager:   linux
Project name:      docker-image|hello-world
Docker image:      hello-world
Licenses:          enabled

✓ Tested 0 dependencies for known issues, no vulnerable paths found.

Note that we do not currently have vulnerability data for your image.

スキャン結果詳細

イメージを作り出すために用いられた Dockerfile を指定することで、Docker イメージに関する詳細なスキャン結果を得ることができます。 コマンド文法はdocker scan --file <Dockerfileへのパス> <Dockerイメージ>というものです。

たとえばテストイメージに対してそのオプションを指定すると、以下のような結果が表示されます。

$ docker scan --file Dockerfile docker-scan:e2e
Testing docker-scan:e2e
...
✗ High severity vulnerability found in perl
  Description: Integer Overflow or Wraparound
  Info: https://snyk.io/vuln/SNYK-DEBIAN10-PERL-570802
  Introduced through: git@1:2.20.1-2+deb10u3, meta-common-packages@meta
  From: git@1:2.20.1-2+deb10u3 > perl@5.28.1-6
  From: git@1:2.20.1-2+deb10u3 > liberror-perl@0.17027-2 > perl@5.28.1-6
  From: git@1:2.20.1-2+deb10u3 > perl@5.28.1-6 > perl/perl-modules-5.28@5.28.1-6
  and 3 more...
  Introduced by your base image (golang:1.14.6)

Organization:      docker-desktop-test
Package manager:   deb
Target file:       Dockerfile
Project name:      docker-image|99138c65ebc7
Docker image:      99138c65ebc7
Base image:        golang:1.14.6
Licenses:          enabled

Tested 200 dependencies for known issues, found 157 issues.

According to our scan, you are currently using the most secure version of the selected base image

ベースイメージの除外

--fileフラグを使って docker scan を行う場合に--exclude-baseフラグを同時に指定することができます。 このフラグは、ぜい弱性スキャン結果からベースイメージ(Dockerfile においてFROMディレクティブにより指定されたもの)を除外します。 たとえば以下のとおりです。

$ docker scan --file Dockerfile --exclude-base docker-scan:e2e
Testing docker-scan:e2e
...
✗ Medium severity vulnerability found in libidn2/libidn2-0
  Description: Improper Input Validation
  Info: https://snyk.io/vuln/SNYK-DEBIAN10-LIBIDN2-474100
  Introduced through: iputils/iputils-ping@3:20180629-2+deb10u1, wget@1.20.1-1.1, curl@7.64.0-4+deb10u1, git@1:2.20.1-2+deb10u3
  From: iputils/iputils-ping@3:20180629-2+deb10u1 > libidn2/libidn2-0@2.0.5-1+deb10u1
  From: wget@1.20.1-1.1 > libidn2/libidn2-0@2.0.5-1+deb10u1
  From: curl@7.64.0-4+deb10u1 > curl/libcurl4@7.64.0-4+deb10u1 > libidn2/libidn2-0@2.0.5-1+deb10u1
  and 3 more...
  Introduced in your Dockerfile by 'RUN apk add -U --no-cache wget tar'



Organization:      docker-desktop-test
Package manager:   deb
Target file:       Dockerfile
Project name:      docker-image|99138c65ebc7
Docker image:      99138c65ebc7
Base image:        golang:1.14.6
Licenses:          enabled

Tested 200 dependencies for known issues, found 16 issues.

JSON 書式による出力

コマンドに対して--jsonフラグを指定することで、スキャン結果を JSON 書式により表示することができます。 たとえば以下のとおりです。

$ docker scan --json hello-world
{
  "vulnerabilities": [],
  "ok": true,
  "dependencyCount": 0,
  "org": "docker-desktop-test",
  "policy": "# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.\nversion: v1.19.0\nignore: {}\npatch: {}\n",
  "isPrivate": true,
  "licensesPolicy": {
    "severities": {},
    "orgLicenseRules": {
      "AGPL-1.0": {
        "licenseType": "AGPL-1.0",
        "severity": "high",
        "instructions": ""
      },
      ...
      "SimPL-2.0": {
        "licenseType": "SimPL-2.0",
        "severity": "high",
        "instructions": ""
      }
    }
  },
  "packageManager": "linux",
  "ignoreSettings": null,
  "docker": {
    "baseImageRemediation": {
      "code": "SCRATCH_BASE_IMAGE",
      "advice": [
        {
          "message": "Note that we do not currently have vulnerability data for your image.",
          "bold": true,
          "color": "yellow"
        }
      ]
    },
    "binariesVulns": {
      "issuesData": {},
      "affectedPkgs": {}
    }
  },
  "summary": "No known vulnerabilities",
  "filesystemPolicy": false,
  "uniqueCount": 0,
  "projectName": "docker-image|hello-world",
  "path": "hello-world"
}

--jsonフラグに加えて--group-issuesフラグを利用することもできます。 これはスキャン報告において 1 つのぜい弱性を 1 度だけ表示するものです。

$ docker scan --json --group-issues docker-scan:e2e
{
    {
      "title": "Improper Check for Dropped Privileges",
      ...
      "packageName": "bash",
      "language": "linux",
      "packageManager": "debian:10",
      "description": "## Overview\nAn issue was discovered in disable_priv_mode in shell.c in GNU Bash through 5.0 patch 11. By default, if Bash is run with its effective UID not equal to its real UID, it will drop privileges by setting its effective UID to its real UID. However, it does so incorrectly. On Linux and other systems that support \"saved UID\" functionality, the saved UID is not dropped. An attacker with command execution in the shell can use \"enable -f\" for runtime loading of a new builtin, which can be a shared object that calls setuid() and therefore regains privileges. However, binaries running with an effective UID of 0 are unaffected.\n\n## References\n- [CONFIRM](https://security.netapp.com/advisory/ntap-20200430-0003/)\n- [Debian Security Tracker](https://security-tracker.debian.org/tracker/CVE-2019-18276)\n- [GitHub Commit](https://github.com/bminor/bash/commit/951bdaad7a18cc0dc1036bba86b18b90874d39ff)\n- [MISC](http://packetstormsecurity.com/files/155498/Bash-5.0-Patch-11-Privilege-Escalation.html)\n- [MISC](https://www.youtube.com/watch?v=-wGtxJ8opa8)\n- [Ubuntu CVE Tracker](http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-18276)\n",
      "identifiers": {
        "ALTERNATIVE": [],
        "CVE": [
          "CVE-2019-18276"
        ],
        "CWE": [
          "CWE-273"
        ]
      },
      "severity": "low",
      "severityWithCritical": "low",
      "cvssScore": 7.8,
      "CVSSv3": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/E:F",
      ...
      "from": [
        "docker-image|docker-scan@e2e",
        "bash@5.0-4"
      ],
      "upgradePath": [],
      "isUpgradable": false,
      "isPatchable": false,
      "name": "bash",
      "version": "5.0-4"
    },
    ...
    "summary": "880 vulnerable dependency paths",
      "filesystemPolicy": false,
      "filtered": {
        "ignore": [],
        "patch": []
      },
      "uniqueCount": 158,
      "projectName": "docker-image|docker-scan",
      "platform": "linux/amd64",
      "path": "docker-scan:e2e"
}

ぜい弱性のもとになる情報はfromの項目から知ることができます。

依存パッケージツリーの確認

イメージの依存パッケージを確認するには --dependency-tree フラグを利用します。 これはスキャン前に、依存パッケージをすべて表示するものです。 たとえば以下です。

$ docker scan --dependency-tree debian:buster

$ docker-image|99138c65ebc7 @ latest
     ├─ ca-certificates @ 20200601~deb10u1
     │  └─ openssl @ 1.1.1d-0+deb10u3
     │     └─ openssl/libssl1.1 @ 1.1.1d-0+deb10u3
     ├─ curl @ 7.64.0-4+deb10u1
     │  └─ curl/libcurl4 @ 7.64.0-4+deb10u1
     │     ├─ e2fsprogs/libcom-err2 @ 1.44.5-1+deb10u3
     │     ├─ krb5/libgssapi-krb5-2 @ 1.17-3
     │     │  ├─ e2fsprogs/libcom-err2 @ 1.44.5-1+deb10u3
     │     │  ├─ krb5/libk5crypto3 @ 1.17-3
     │     │  │  └─ krb5/libkrb5support0 @ 1.17-3
     │     │  ├─ krb5/libkrb5-3 @ 1.17-3
     │     │  │  ├─ e2fsprogs/libcom-err2 @ 1.44.5-1+deb10u3
     │     │  │  ├─ krb5/libk5crypto3 @ 1.17-3
     │     │  │  ├─ krb5/libkrb5support0 @ 1.17-3
     │     │  │  └─ openssl/libssl1.1 @ 1.1.1d-0+deb10u3
     │     │  └─ krb5/libkrb5support0 @ 1.17-3
     │     ├─ libidn2/libidn2-0 @ 2.0.5-1+deb10u1
     │     │  └─ libunistring/libunistring2 @ 0.9.10-1
     │     ├─ krb5/libk5crypto3 @ 1.17-3
     │     ├─ krb5/libkrb5-3 @ 1.17-3
     │     ├─ openldap/libldap-2.4-2 @ 2.4.47+dfsg-3+deb10u2
     │     │  ├─ gnutls28/libgnutls30 @ 3.6.7-4+deb10u4
     │     │  │  ├─ nettle/libhogweed4 @ 3.4.1-1
     │     │  │  │  └─ nettle/libnettle6 @ 3.4.1-1
     │     │  │  ├─ libidn2/libidn2-0 @ 2.0.5-1+deb10u1
     │     │  │  ├─ nettle/libnettle6 @ 3.4.1-1
     │     │  │  ├─ p11-kit/libp11-kit0 @ 0.23.15-2
     │     │  │  │  └─ libffi/libffi6 @ 3.2.1-9
     │     │  │  ├─ libtasn1-6 @ 4.13-3
     │     │  │  └─ libunistring/libunistring2 @ 0.9.10-1
     │     │  ├─ cyrus-sasl2/libsasl2-2 @ 2.1.27+dfsg-1+deb10u1
     │     │  │  └─ cyrus-sasl2/libsasl2-modules-db @ 2.1.27+dfsg-1+deb10u1
     │     │  │     └─ db5.3/libdb5.3 @ 5.3.28+dfsg1-0.5
     │     │  └─ openldap/libldap-common @ 2.4.47+dfsg-3+deb10u2
     │     ├─ nghttp2/libnghttp2-14 @ 1.36.0-2+deb10u1
     │     ├─ libpsl/libpsl5 @ 0.20.2-2
     │     │  ├─ libidn2/libidn2-0 @ 2.0.5-1+deb10u1
     │     │  └─ libunistring/libunistring2 @ 0.9.10-1
     │     ├─ rtmpdump/librtmp1 @ 2.4+20151223.gitfa8646d.1-2
     │     │  ├─ gnutls28/libgnutls30 @ 3.6.7-4+deb10u4
     │     │  ├─ nettle/libhogweed4 @ 3.4.1-1
     │     │  └─ nettle/libnettle6 @ 3.4.1-1
     │     ├─ libssh2/libssh2-1 @ 1.8.0-2.1
     │     │  └─ libgcrypt20 @ 1.8.4-5
     │     └─ openssl/libssl1.1 @ 1.1.1d-0+deb10u3
     ├─ gnupg2/dirmngr @ 2.2.12-1+deb10u1
    ...

Organization:      docker-desktop-test
Package manager:   deb
Project name:      docker-image|99138c65ebc7
Docker image:      99138c65ebc7
Licenses:          enabled

Tested 200 dependencies for known issues, found 157 issues.

For more free scans that keep your images secure, sign up to Snyk at https://dockr.ly/3ePqVcp.

ぜい弱性データの詳細については Docker Vulnerability Scanning CLI Cheat Sheet を参照してください。

ぜい弱性レベルの表示制限

Docker スキャンにおいては--severityフラグを利用することで、ぜい弱性レベルを選んで表示することができます。 この--severityフラグには、レポート内において確認したいぜい弱性レベルに応じてlowmediumhighのいずれかを指定します。 たとえばこのレベルをmediumに設定した場合、スキャンレポートにはぜい弱性レベルが medium(中程度)と high(重要)のものが表示されます。

$ docker scan --severity=medium docker-scan:e2e 
./bin/docker-scan_darwin_amd64 scan --severity=medium docker-scan:e2e

Testing docker-scan:e2e...

✗ Medium severity vulnerability found in sqlite3/libsqlite3-0
  Description: Divide By Zero
  Info: https://snyk.io/vuln/SNYK-DEBIAN10-SQLITE3-466337
  Introduced through: gnupg2/gnupg@2.2.12-1+deb10u1, subversion@1.10.4-1+deb10u1, mercurial@4.8.2-1+deb10u1
  From: gnupg2/gnupg@2.2.12-1+deb10u1 > gnupg2/gpg@2.2.12-1+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3
  From: subversion@1.10.4-1+deb10u1 > subversion/libsvn1@1.10.4-1+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3
  From: mercurial@4.8.2-1+deb10u1 > python-defaults/python@2.7.16-1 > python2.7@2.7.16-2+deb10u1 > python2.7/libpython2.7-stdlib@2.7.16-2+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3

✗ Medium severity vulnerability found in sqlite3/libsqlite3-0
  Description: Uncontrolled Recursion
...
✗ High severity vulnerability found in binutils/binutils-common
  Description: Missing Release of Resource after Effective Lifetime
  Info: https://snyk.io/vuln/SNYK-DEBIAN10-BINUTILS-403318
  Introduced through: gcc-defaults/g++@4:8.3.0-1
  From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/binutils-common@2.31.1-16
  From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/libbinutils@2.31.1-16 > binutils/binutils-common@2.31.1-16
  From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/binutils-x86-64-linux-gnu@2.31.1-16 > binutils/binutils-common@2.31.1-16
  and 4 more...

Organization:      docker-desktop-test
Package manager:   deb
Project name:      docker-image|docker-scan
Docker image:      docker-scan:e2e
Platform:          linux/amd64
Licenses:          enabled

Tested 200 dependencies for known issues, found 37 issues.

プロバイダー認証

すでに Snyk アカウントを持っている場合は、Snyk の API トークン を直接利用することができます。

$ docker scan --login --token <Synk認証トークン>

Your account has been authenticated. Snyk is now ready to be used.

トークンを指定せずに--loginフラグを用いた場合、Snyk のウェブサイトにリダイレクトされてログインを行います。

前提条件

Docker イメージに対してぜい弱性スキャンを実行するには、以下を満たしていることが必要です。

  1. Docker Desktop の最新版をダウンロードしインストールしていること。

  2. Docker Hub にサインインしていること。

  3. Docker Desktop メニューにおいて Sign in/ Create Docker ID を選択していること。 あるいはターミナル画面を開いてdocker loginを実行していること。

  4. (任意作業)スキャンを行うために Snyk アカウント を生成していること。 または Docker Hub アカウントとともに利用できるものとして Snyk 社が提供する、月単位の追加無償スキャンを利用していること。

インストールができているかどうかをdocker scan --versionを実行して確認してください。 コマンド実行によって、docker scan の現行バージョン、および Snyk エンジンのバージョンを表示されます。 たとえば以下のとおりです。

$ docker scan --version
Version:    v0.5.0
Git commit: 5a09266
Provider:   Snyk (1.432.0)

メモ

Docker Scan はデフォルトで、インストールされている Snyk バイナリを利用します。 これが利用できなかった場合は、Docker Desktop に埋め込まれている Snyk バイナリが利用されます。 必要となる Snyk の最低バージョンは1.385.0です。

サポートされているオプション

高度なコマンドdocker scanでは、イメージの名前または ID を使ってローカルイメージをスキャンします。 このコマンドは以下のオプションをサポートしています。

オプション 内容説明
--accept-license サードパーティー製プロバイダーのライセンスを承認します。
--dependency-tree スキャン結果において依存パッケージのツリーを表示します。
--exclude-base スキャンにあたってベースイメージは取り除きます。このオプションには --file オプションの設定が必要です。
-f, --file string イメージに対応する Dockerfile を指定します。このオプションはスキャンの詳細結果を表示します。
--json スキャン結果を JSON 書式により表示します。
--login 任意に指定されたトークン(--token フラグ利用)を使って Snyk にログインします。あるいはウェブベースのトークンを利用します。
--reject-license サードパーティー製プロバイダーのライセンスを否認します。
--severity string 指定されたレベル以上のぜい弱性のみを表示します。(low、medium、high)
--token string 認証トークンを使ってサードパーティー製スキャンプロバイダーにログインします。
--version Docker Scan プラグインのバージョンを表示します。

既知の問題

WSL 2 の場合

  • ぜい弱性スキャン機能は Alpine ディストリビューションにおいては動作しません。
  • ディストリビューション Debian または OpenSUSE を利用している場合、ログイン処理は--tokenフラグを利用した場合にのみ動作します。その場合、Synk ウェブサイトへはリダイレクトされません。

フィードバック

Docker ローカルイメージに対するぜい弱性スキャン機能をご利用いただき、ありがとうございます。 みなさんからのフィードバックを頂くことが重要と考えています。 フィードバックは GitHub リポジトリ内の scan-cli-plugin において issue を生成してお知らせください。

Docker, scan, Snyk, images, local, CVE, vulnerability, security