Snyk で Amazon ECR のイメージを脆弱性スキャンしてみた

Snyk から ECR にあるイメージの脆弱性スキャンをやってみました。
2022.07.10

Snyk から ECR に保存されているイメージに対して脆弱性スキャンを実施し、どのような実行結果を取得できるのか確認したかったので試してみました。

Snyk と AWS の連携は IAM ロールを作成するだけで簡単でしたので主に Snyk 設定と、なにを確認できたのかを中心に紹介します。

画像引用: Configure integration for Amazon Elastic Container Registry (ECR) - Snyk User Docs

Quick Start Deployment Guide をやってみる

Snyk Containerの機能で ECR と統合してイメージの脆弱性スキャンを実施するまでやっていきます。

Snyk Developer-First Security on the AWS Cloudに沿って進めます。

以下の記事で Lambda の例が紹介されており、こちらの ECR 版の記事になります。

準備

AWS

ECR のリポジトリの作成とイメージの Push を事前にしておきます。今回は過去に検証で利用していたリポジトリを流用します。ほどよく古いので脆弱性の検知に都合がよいイメージになっているはずです。

Snyk

画面上部の歯車アイコンから Settings を開き、Organizaiont IDを控えます。

次は Snyk が利用している AWS アカウント ID を確認する手順の意味がわからなかったので補足します。 まず Integrations を選択します。

ECE ではなく Lambda を選択します。ECR の設定をするのに「なぜ Lambda を開く必要があるのか」意味がわかりませんでした。

すると、Lambda の設定画面から Snyk で利用している AWS アカウント ID を確認できるので控えます

調べたところ ECR の設定画面からも AWS アカウント ID を確認できたのですが非常にわかりにくいです。

そのため、Lambda の設定画面を参照するような手順としたのではないかと推測されます。

IAM ロールの作成

IAM ロールの作成の Cloudformation テンプレートが用意されているため利用します。

Snyk Security - クイックスタート

スタックを実行するリージョンをap-northeast-1に変更しました。デフォルトだとus-east-1で開かれるはずです。控えていた ID を入力してスタックを実行します。

5分もしないでデプロイが完了します。出力結果から以下のパラメーターを控えます。Snyk 側に登録で必要になります。

Snyk の ECR 統合設定

プロジェクトを追加します。

ECRを選択します。

Cloudformation 出力結果から控えた情報を入力して保存します。

ECR のイメージの同期します。

統合したAWS アカウントの ECR リポジトリが Snyk から確認できるようになりました。試しに古そうなリポジトリと、Windows コンテナのリポジトリを選択して登録してみました。

リポジトリを展開するとタグを確認できて、タグ単位で登録もできるようです。latest タグをつけておけば常に最新のイメージのみスキャン対象といったことができそうですね。

スキャン結果確認

しばらく待つとスキャン結果が返ってきました。sample-windows-iisの結果がなにもないのでログを確認します。

ログから2GB を超えるイメージはスキャンできないことを学びました。

Job started: 10 July 2022, 10:18:34
Processed sample-windows-iis:flag from ECR
Image size exceeds allowed size (2.656 GB > 2.000 GB)
0 projects created
Job completed: 10 July 2022, 10:18:38

以降はsample3-webappのリポジトリの内容を確認します。View Reportをから詳しくみていきます。

View Report

Summary に情報が反映されるまでしばらく時間かかりました。更新しても直近の ECR をスキャンした情報が載ってこないので表示されるまで待ってください。反映されるとSummaryタブから重大度が CRITICAL のものが何個とか一覧で確認できました。

プロジェクト名で絞り込んでいるのですが、リポジトリ+タグの組み合わせが1プロジェクトとして登録されています。

Issuesタブから具体的な脆弱性の内容を確認できます。

OS Command Injection を選択すると CVE の内容確認できます。真っ先に修正方法が載っているところが好きです。あと Twitter でトレンドといった話題度が表示されるのはおもしろいですね。

9 projects を選択すると脆弱性に該当するプロジェクト(リポジトリ名 + タグ)を確認できます。

Dependenciesタグからイメージ内のライブラリのバージョン一覧を確認できます。

検出されたライブラリ数が異様に少ない感じがします。リポジトリに放置されていたイメージの生成元の Dockerfile を発掘して確認したところdistroless に Go バイナリ1個だけでしたので妥当な検出結果でした。

Dockerfile

FROM public.ecr.aws/bitnami/golang:1.16 as builder

WORKDIR /app

COPY . .
RUN go mod download
RUN go mod tidy
RUN go build -o web-server .

FROM gcr.io/distroless/base-debian10:latest

WORKDIR /app
COPY --from=builder /app/web-server /app/web-server

EXPOSE 8080
ENTRYPOINT ["/app/web-server"]

イメージを更新してみる

(Dockerfile を発掘したので)脆弱性を検出されたイメージを更新して再スキャンをかけてみます。ベースイメージは distroless を使っていたこともありビルドし直して ECR に latestタグをつけてプッシュします。

$ docker image build . -t sample3-webapp:latest
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker tag sample3-webapp:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/sample3-webapp:latest
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/sample3-webapp:latest

10か月ぶりの更新でした。ベースイメージが新しくなったので再度スキャンを実行します。

snky は Add Project から ECR の再同期が必要でした。

latestタグにチェックを入れて追加します。

スキャン結果が表示されました。最新のベースイメージにはリスクはありませんでした。

展開できることに気づいて Debian アイコンのタグ名を選択してみました。

ベースイメージ名を snky から確認できました。つい先ほどまで何のイメージかわからなく Dockerfile を発掘していた身としてはありがたい。Issuesの情報もイメージタグ画面から確認できました。

同様にDependenciesタブもあり、ライブラリの情報を一覧で確認できます。

おわりに

簡単な紹介ではありましたが、AWS クイックスタートから Snky をはじめて使ってみてわからなかったところを補足しました。同じくちょっとやってみるかと思ってよくわからないときは参考にしていただけると嬉しいです。

その他に学んだことは、Snyk は Organization 単位で統合できる AWS アカウント(クロスアカウントの IAM ロール)を設定するようです。プロジェクトは(ECR のリポジトリ名 + タグ)単位の登録であったため、プロジェクト毎に AWS アカウントを統合するわけではありませんでした。

行き詰まったときはSnyk User Documentationで確認した方が早かったです。

参考