はじめに
Ubuntu 20.04 で docker scan をやってみました。
doceker scan は CLI 上からイメージの脆弱性を検査する docker コマンドの機能です。
https://codezine.jp/article/detail/14347
スキャナは snyk の脆弱性スキャン SaaS を利用しています。
docker CLI はイメージの情報を syk のサーバに送信して、スキャン結果を出力することをやってくれます。
環境
動作環境は以下のとおりです。
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
$ docker --version
Docker version 20.10.11, build dea9396
$ docker scan --version
Version: v0.9.0
Git commit: b05830d
Provider: Snyk (1.563.0 (standalone))
スキャンしようとするが・・・
Docker のマニュアルに沿ってとりあえずスキャンしようとしたもののいくつかエラーが出ました・・・。
https://matsuand.github.io/docs.docker.jp.onthefly/engine/scan/
順番に処置していきましょう。
ログインを要求された
スキャンの前に DockerHub へのログインを要求されました。
$ docker scan hello-world
Docker Scan relies upon access to Snyk, a third party provider, do you consent to proceed using Snyk? (y/N)
y
failed to get DockerScanID: You need to be logged in to Docker Hub to use scan feature.
please login to Docker Hub using the Docker Login command
docker scan
は DockerHub の無料アカウントを持っていると毎月 10 回まで無料で実行できる機能です。
有償アカウントだとさらにスキャンできる回数が増えます。
とりあえず docker login
しましょう。
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ******
Password:
WARNING! Your password will be stored unencrypted in /home/******/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
400 bad request
docker login
後にスキャンしようとするものの、ふたたびエラーが出ました。
$ docker scan hello-world
failed to get DockerScanID: bad status code "400 Bad Request"
docker scan
は、 snyk の脆弱性スキャン SaaS を使用するツールで、snyk のアカウントを作らないとスキャンできません。
DockerScanID というのは snyk のアカウントのことのようです。メンドクサイですね。
--login
オプションで snyk にスキャンします。
$ docker scan --login
To authenticate your account, open the below URL in your browser.
After your authentication is complete, return to this prompt to start using Snyk.
https://snyk.io/login?******
表示された URL をブラウザで表示します。
Docker ID と紐づけたいので、Docker ID
ボタンをクリックします。
Authenticate
ボタンをクリックします。
認証されました。
しかし、コマンドラインを見ると認証失敗のエラーが出てます。
Authentication failed. Please check the API token on https://snyk.io
よくわかりませんね・・・。
以下のサイトを参考に
https://qiita.com/yomon8/items/e5c1b20719b5c6f7911f
ブラウザで snyk にログインして、
アカウント設定画面から click to show
をクリックして、API キーを表示します。
--token
オプションの引数に API キーを指定してログインを実行します。
$ docker scan --login --token ****************************
Your account has been authenticated. Snyk is now ready to be used.
これでようやくスキャンの準備が整いました。
スキャン実行
脆弱性を含まないイメージをスキャンする
docker 公式のイメージ hello-world
をスキャンしてみます。
$ docker scan hello-world
Testing hello-world...
Organization: kannkyo
Package manager: linux
Project name: docker-image|hello-world
Docker image: hello-world
Platform: linux/amd64
Licenses: enabled
✓ Tested hello-world for known issues, no vulnerable paths found.
Note that we do not currently have vulnerability data for your image.
脆弱性が検出されませんでした。
安全なイメージですね。
脆弱性を含むイメージをスキャンする
docker 公式のイメージ httpd:2.4.51
をスキャンしてみます。
脅威度の高い脆弱性だけを対象とするため、--severity=high
オプションをつけました。
$ docker scan --severity=high httpd:2.4.51
Testing httpd:2.4.51...
✗ High severity vulnerability found in curl/libcurl4
Description: Cleartext Transmission of Sensitive Information
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585138
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ Critical severity vulnerability found in glibc/libc-bin
Description: Use After Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
Introduced through: glibc/libc-bin@2.31-13+deb11u2, meta-common-packages@meta
From: glibc/libc-bin@2.31-13+deb11u2
From: meta-common-packages@meta > glibc/libc6@2.31-13+deb11u2
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ Critical severity vulnerability found in curl/libcurl4
Description: Double Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585150
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
Organization: kannkyo
Package manager: deb
Project name: docker-image|httpd
Docker image: httpd:2.4.51
Platform: linux/amd64
Base image: httpd:2.4.51-bullseye
Licenses: enabled
Tested 115 dependencies for known issues, found 3 issues.
According to our scan, you are currently using the most secure version of the selected base image
実行ログの最後の 2 行がスキャン結果のサマリーです。
Tested 115 dependencies for known issues, found 3 issues.
115の依存関係について既知の問題をテストし、3つの問題を発見しました。
According to our scan, you are currently using the most secure version of the selected base image
スキャンの結果、お客様は現在、選択されたベースイメージの最も安全なバージョンを使用しています。
curl, gtlibc についての 3 つの脆弱性が発見されました。
また、脆弱性が含まれるものの、httpd
イメージの中では最も安全なバージョンを使用していることがわかりました。
3 つの脆弱性の詳細を見てみます。
パッケージ | 脆弱性 | CVE | 脅威度 |
---|---|---|---|
curl/libcurl4 | Cleartext Transmission of Sensitive Information in curl | CVE-2021-22946 | 7.5 |
glibc/libc-bin | Use After Free in glibc | CVE-2021-33574 | 9.8 |
curl/libcurl4 | Double Free in curl | CVE-2021-22945 | 9.1 |
curl と glibc についての脆弱性が出てます。
脅威度は最大で 10 です。9.8 はかなり高いです。
使わないパッケージであれば、httpd
イメージから削除した別のイメージを作ったほうが良いです。
Dockerfileとベースイメージに脆弱性を含むイメージをスキャンする
次に、ベースイメージに先程の httpd:2.4.51
を使用し、さらに Dockerfile に脆弱性を埋め込んだイメージをスキャンします。
スキャン対象のイメージの Dockerfile は以下です。
https://github.com/kannkyo/buggy-docker/blob/v0.0.1/Dockerfile
$ docker scan ghcr.io/kannkyo/buggy-docker:v0.0.1
Testing ghcr.io/kannkyo/buggy-docker:v0.0.1...
✗ Low severity vulnerability found in tar
Description: CVE-2005-2541
Info: https://snyk.io/vuln/SNYK-DEBIAN11-TAR-523480
Introduced through: meta-common-packages@meta
From: meta-common-packages@meta > tar@1.34+dfsg-1
✗ Low severity vulnerability found in systemd/libsystemd0
Description: Authentication Bypass
Info: https://snyk.io/vuln/SNYK-DEBIAN11-SYSTEMD-1291054
Introduced through: systemd/libsystemd0@247.3-6, apt@2.2.4, util-linux/bsdutils@1:2.36.1-8, util-linux/mount@2.36.1-8, systemd/libudev1@247.3-6
From: systemd/libsystemd0@247.3-6
From: apt@2.2.4 > systemd/libsystemd0@247.3-6
From: util-linux/bsdutils@1:2.36.1-8 > systemd/libsystemd0@247.3-6
and 5 more...
...
✗ Medium severity vulnerability found in curl/libcurl4
Description: Insufficient Verification of Data Authenticity
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585148
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
✗ High severity vulnerability found in curl/libcurl4
Description: Cleartext Transmission of Sensitive Information
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585138
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
✗ Critical severity vulnerability found in glibc/libc-bin
Description: Use After Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
Introduced through: glibc/libc-bin@2.31-13+deb11u2, meta-common-packages@meta
From: glibc/libc-bin@2.31-13+deb11u2
From: meta-common-packages@meta > glibc/libc6@2.31-13+deb11u2
✗ Critical severity vulnerability found in curl/libcurl4
Description: Double Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585150
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Organization: kannkyo
Package manager: deb
Project name: docker-image|ghcr.io/kannkyo/buggy-docker
Docker image: ghcr.io/kannkyo/buggy-docker:v0.0.1
Platform: linux/amd64
Base image: httpd:2.4.51-bullseye
Licenses: enabled
Tested 115 dependencies for known issues, found 52 issues.
According to our scan, you are currently using the most secure version of the selected base image
52 件の脆弱性が検出されました。
多すぎてよくわからないので、docker scan
コマンドのオプションを使ってもう少し調べてみます。
ベースイメージの脆弱性を対象外にする
--exclude-base
オプションを使用して、ベースイメージ httpd
の脆弱性を対象外にします。
これで、自分が作った Dockerfile による脆弱性だけを抽出します。
$ docker scan --file Dockerfile --exclude-base ghcr.io/kannkyo/buggy-docker:v0.0.1
Testing ghcr.io/kannkyo/buggy-docker:v0.0.1...
Organization: kannkyo
Package manager: deb
Target file: /app/Dockerfile
Project name: docker-image|ghcr.io/kannkyo/buggy-docker
Docker image: ghcr.io/kannkyo/buggy-docker:v0.0.1
Platform: linux/amd64
Base image: httpd:2.4.51
Licenses: enabled
Tested 115 dependencies for known issues, found 0 issues.
According to our scan, you are currently using the most secure version of the selected base image
脆弱性が検出されませんでした。
どうやら Dockerfile についての脆弱性は検出できないようです。
脅威度の高い脆弱性の情報を詳細に出力する
--serverity
オプションと --dependency-tree
オプションを使って次の脅威度の脆弱性を含むパッケージの情報を詳細に出力します。
--dependency-tree
オプションは、脆弱性の依存関係を可視化するオプションです。
$ docker scan --dependency-tree --severity=high ghcr.io/kannkyo/buggy-docker:v0.0.1
docker-image|ghcr.io/kannkyo/buggy-docker @ v0.0.1
...
├─ curl/libcurl4 @ 7.74.0-1.3+b1
│ ├─ brotli/libbrotli1 @ 1.0.9-2+b2
│ ├─ krb5/libgssapi-krb5-2 @ 1.18.3-6+deb11u1
│ │ ├─ e2fsprogs/libcom-err2 @ 1.46.2-2
│ │ ├─ krb5/libk5crypto3 @ 1.18.3-6+deb11u1
│ │ └─ krb5/libkrb5-3 @ 1.18.3-6+deb11u1
│ │ ├─ e2fsprogs/libcom-err2 @ 1.46.2-2
│ │ ├─ keyutils/libkeyutils1 @ 1.6.1-2
│ │ ├─ krb5/libk5crypto3 @ 1.18.3-6+deb11u1
│ │ └─ openssl/libssl1.1 @ 1.1.1k-1+deb11u1
│ ├─ libidn2/libidn2-0 @ 2.3.0-5
│ ├─ libpsl/libpsl5 @ 0.21.0-1.2
│ │ ├─ libidn2/libidn2-0 @ 2.3.0-5
│ │ └─ libunistring/libunistring2 @ 0.9.10-4
│ ├─ libssh2/libssh2-1 @ 1.9.0-2
│ │ └─ libgcrypt20 @ 1.8.7-6
│ │ └─ libgpg-error/libgpg-error0 @ 1.38-2
│ ├─ nghttp2/libnghttp2-14 @ 1.43.0-1
│ ├─ openldap/libldap-2.4-2 @ 2.4.57+dfsg-3
│ ├─ openssl/libssl1.1 @ 1.1.1k-1+deb11u1
│ └─ rtmpdump/librtmp1 @ 2.4+20151223.gitfa8646d.1-2+b2
│ ├─ gmp/libgmp10 @ 2:6.2.1+dfsg-1
│ ├─ gnutls28/libgnutls30 @ 3.7.1-5
│ ├─ nettle/libhogweed6 @ 3.7.3-1
│ └─ nettle/libnettle8 @ 3.7.3-1
...
├─ glibc/libc-bin @ 2.31-13+deb11u2
...
└─ xxhash/libxxhash0 @ 0.8.0-2
Testing ghcr.io/kannkyo/buggy-docker:v0.0.1...
✗ High severity vulnerability found in curl/libcurl4
Description: Cleartext Transmission of Sensitive Information
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585138
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
✗ Critical severity vulnerability found in glibc/libc-bin
Description: Use After Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
Introduced through: glibc/libc-bin@2.31-13+deb11u2, meta-common-packages@meta
From: glibc/libc-bin@2.31-13+deb11u2
From: meta-common-packages@meta > glibc/libc6@2.31-13+deb11u2
✗ Critical severity vulnerability found in curl/libcurl4
Description: Double Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585150
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Organization: kannkyo
Package manager: deb
Project name: docker-image|ghcr.io/kannkyo/buggy-docker
Docker image: ghcr.io/kannkyo/buggy-docker:v0.0.1
Platform: linux/amd64
Base image: httpd:2.4.51-bullseye
Licenses: enabled
Tested 115 dependencies for known issues, found 3 issues.
According to our scan, you are currently using the most secure version of the selected base image
すべての脆弱性の依存関係が出力されました。 --severity
オプションを併用しても、依存関係をフィルタできないみたいですね。
脆弱性を含むイメージをスキャンする
Dockerfile の中で cron
パッケージをインストールしたパッケージを作成します。
https://github.com/kannkyo/buggy-docker/blob/v0.0.2/Dockerfile#L15
cron
をインストールする際に、exim4-config
がインストールされます。
$ apt-get install cron
The following NEW packages will be installed:
ca-certificates cron exim4-base exim4-config exim4-daemon-light gsasl-common guile-2.2-libs libevent-2.1-7 libfribidi0 libgc1
libgnutls-dane0 libgpm2 libgsasl7 libidn11 libltdl7 libmailutils7 libmariadb3 libmpdec3 libncurses6 libncursesw6 libntlm0 libpython3.9
libpython3.9-minimal libpython3.9-stdlib libreadline8 libsqlite3-0 libunbound8 mailutils mailutils-common mariadb-common media-types
mysql-common netbase openssl psmisc readline-common sensible-utils
0 upgraded, 37 newly installed, 0 to remove and 0 not upgraded.
exim4-config
は、インジェクション攻撃に対する脆弱性 CVE-2021-38371 を含んでいます。
新しいイメージをスキャンします。
$ docker scan --severity=high ghcr.io/kannkyo/buggy-docker:v0.0.2
Testing ghcr.io/kannkyo/buggy-docker:v0.0.2...
✗ High severity vulnerability found in exim4/exim4-config
Description: Arbitrary Code Injection
Info: https://snyk.io/vuln/SNYK-DEBIAN11-EXIM4-1538494
Introduced through: exim4/exim4-config@4.94.2-7, exim4/exim4-base@4.94.2-7, exim4/exim4-daemon-light@4.94.2-7
From: exim4/exim4-config@4.94.2-7
From: exim4/exim4-base@4.94.2-7 > exim4/exim4-config@4.94.2-7
From: exim4/exim4-base@4.94.2-7
and 2 more...
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ High severity vulnerability found in curl/libcurl4
Description: Cleartext Transmission of Sensitive Information
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585138
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ Critical severity vulnerability found in python3.9/libpython3.9-minimal
Description: Improper Input Validation
Info: https://snyk.io/vuln/SNYK-DEBIAN11-PYTHON39-1290158
Introduced through: python3.9/libpython3.9-minimal@3.9.2-1, mailutils/libmailutils7@1:3.10-3+b1, python3.9/libpython3.9-stdlib@3.9.2-1, python3.9/libpython3.9@3.9.2-1
From: python3.9/libpython3.9-minimal@3.9.2-1
From: mailutils/libmailutils7@1:3.10-3+b1 > python3.9/libpython3.9@3.9.2-1 > python3.9/libpython3.9-stdlib@3.9.2-1 > python3.9/libpython3.9-minimal@3.9.2-1
From: python3.9/libpython3.9-stdlib@3.9.2-1
and 3 more...
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ Critical severity vulnerability found in glibc/libc-bin
Description: Use After Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-GLIBC-1296898
Introduced through: glibc/libc-bin@2.31-13+deb11u2, meta-common-packages@meta
From: glibc/libc-bin@2.31-13+deb11u2
From: meta-common-packages@meta > glibc/libc6@2.31-13+deb11u2
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
✗ Critical severity vulnerability found in curl/libcurl4
Description: Double Free
Info: https://snyk.io/vuln/SNYK-DEBIAN11-CURL-1585150
Introduced through: curl/libcurl4@7.74.0-1.3+b1
From: curl/libcurl4@7.74.0-1.3+b1
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
Organization: kannkyo
Package manager: deb
Project name: docker-image|ghcr.io/kannkyo/buggy-docker
Docker image: ghcr.io/kannkyo/buggy-docker:v0.0.2
Platform: linux/amd64
Base image: httpd:2.4.51-bullseye
Licenses: enabled
Tested 152 dependencies for known issues, found 5 issues.
According to our scan, you are currently using the most secure version of the selected base image
新しい脆弱性 2 つを含む 5 つの脆弱性が検出されました。
exim4-config
だけでなく libpython3.9-minimal
の脆弱性も検出しました。
新しい脆弱性のスキャン結果をよく見ると、
Image layer: Introduced by your base image (httpd:2.4.51-bullseye)
「ベースイメージで作り込まれた」と書いてあります。誤検知ですね。
脆弱性そのものは検出できても、脆弱性がどのレイヤーに含まれるかという点の精度は甘いようです。
評価
docker scan の 良い点
- Snyk と Docker のアカウントが連携していて、Docker CLI から snyk の脆弱性をスキャンできるのでツール導入の敷居がグッと低いですね。
- パッケージの依存関係をツリー構造で可視化してくれる機能は、すごく便利です。
- 他の脆弱性スキャナーの GitHub Code Scanning には、依存関係を可視化する機能はありません。
- パッケージ A, B, C をインストールした後に、パッケージ A が依存するパッケージ D で脆弱性エラーが出ときとかに解析がすごく楽になります。
docker scan の 悪い点
- スキャンする前のログイン作業は結構面倒でしたね。もう少しわかりやすくならないのでしょうか。
- パッケージの脆弱性は発見できましたが、Dockerfile の脆弱性は発見できませんでした。
- 脆弱性が含まれるレイヤーの識別の精度が甘いという欠点がありました。
まとめ
docker scan
は総じて導入の敷居が低く、簡単にイメージのスキャンができる使いやすいツールでした。
Dockerfile の脆弱性をチェックできる sysdiglabs/benchmark-dockerfile なんかと組み合わせて使えばセキュアなコンテナの開発に役立つかと、思います。
参考サイト
https://snyk.io/learn/docker-security-scanning/
https://f.hubspotusercontent10.net/hubfs/1699665/Docker_CLI_Cheat_Sheet_2021-01-12a.PDF