はじめに
こちらの記事はアドベントカレンダーSnykを使ってセキュリティにまつわる記事を投稿しよう!【PR】Snykの9日目として投稿しています。
Snykは脆弱性スキャンが簡単に自動化でき、修復まで可能なセキュリティプロダクトです。単純なソースコード検査だけでなく、依存しているライブラリの脆弱性やコンテナイメージそのものをスキャンすることができ、非常に強力なツールとなっています。
この記事では、わざと脆弱性を入れ込んだコンテナイメージを作り、Snykで検知できるかどうか試しました。
また、人気のあるOSSライブラリを検査し、見つかった脆弱性にパッチできるPRを自動でSnykから生成してみます。
Snykの脆弱性スキャンの仕組み
ルールベース+機械学習モデルでの精度向上
メインの脆弱性スキャン自体はルールベースの一般的なやり方です。それにフィルタとして、機械学習ベースのモデルで偽陽性・偽陰性を少なくし、検知精度を上げているようです。
また、脆弱性の検知ルールとして、CVEを元に独自のデータベースで管理しており、各CVEに対してわかりやすく説明を加えたり、PRのメッセージをひと目でわかるようにメタデータを付加しているようです。
コンテナイメージスキャン
コンテナイメージを検査するには、実際に動かして検査する方法もあるが、Snykではイメージを動かさずに静的に検査できるため、非常に安全です。静的検査では、イメージ内で使われている依存パッケージとバージョンを検出し、脆弱性を分析してくれます。こちらの公式ドキュメントで詳しい仕組みが書かれてます。
実はDocker scanコマンドで公式に使われてるのがSnykエンジンとのこと!いつの間にかデファクトになってますね。
Docker Scan runs on Snyk engine, providing users with visibility into the security posture of their local Dockerfiles and local images.
https://docs.docker.com/engine/scan/ より
実際にスキャンしてみる
初期登録
Snykの公式の記事があるので、こちらを見てみてください。無料でほとんどの機能が使用できます。GoogleかGitHubアカウント連携ですぐアカウントを作れます。
わざと脆弱性を入れたコンテナをスキャンしてみる【コンテナイメージスキャン】
PythonのウェブアプリフレームワークであるFlaskの古いバージョンを使って、脆弱なサーバーのコンテナイメージを作成し、それをSnykでスキャンしてみます。0.12.0という古いバージョンのFlaskでは、DoSとInput Validationの既知の重大レベルの脆弱性があります。SnykのDBではこちらのリンクでトラックされています。
以下のDockerfileでRUN pip3 install flask==0.12.0
の部分が、脆弱性のあるライブラリをインストールしている部分になります。
# Test to create vulnerable docker image
# Using vulnerable Python library: flask 0.12.0
# https://security.snyk.io/vuln/SNYK-PYTHON-FLASK-451637
FROM python
RUN pip3 install flask==0.12.0
COPY flask_server.py /
CMD python flask_server.py
### flask_server.py ###
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
name = "Hello World"
return name
if __name__ == "__main__":
app.run()
今回はGoogle Cloudのコンテナレジストリにコンテナイメージをアップロードし、それをSnykで脆弱性スキャンしてみます。こちらの公式ドキュメント通りの流れとなります。
- コンテナイメージをビルドし、Google CloudのコンテナレジストリにPush(アップロード)します。ウェブUI上でコンテナイメージがアップロードされたことを確認できると思います。
docker build -t vulnerable-flask .
docker tag vulnerable-flask gcr.io/<自分のGoogle CloudのプロジェクトID>/vulnerable-flask
docker push gcr.io/<自分のGoogle CloudのプロジェクトID>/vulnerable-flask
2.Snykがコンテナレジストリのイメージを読めるよう、Google Cloudでサービスアカウントのキーを作成して、Snykで登録します。
4.数秒ほど待つと、検知結果がUI上で出てくるので、開いてみましょう。結果は以下の通り、SNYK-PYTHON-FLASK-451637の脆弱性がしっかり検知されている事がわかります。
今回はクラウド上のレジストリからコンテナイメージのスキャンを行いましたが、CLIで行うことも可能です!
ただ、その場合は公式ドキュメントにあるとおり、Node、Golang、Javaのみが対応しており、Pythonは2021年12月9日現在ではまだ非対応です。
公式サポートに問い合わせたところ、Pythonは今後対応していく予定があるとのことです。
Unfortunately, Python dependency analysis is indeed not yet supported from the CLI, but only from the CR integrations. See as well the docs from here:
https://docs.snyk.io/products/snyk-container/getting-around-the-snyk-container-ui/detecting-application-vulnerabilities-in-container-images
It is on the roadmap to have it supported as well from the CLI.(参考訳)残念ですが、コンテナイメージのPythonの依存分析については、CLIツールではまだサポートされておりません。その代替案として、コンテナレポジトリからであれば、分析することができます。こちらのドキュメントを参考にして下さいね。今後CLIツールからスキャンできるように、開発計画(ロードマップ)を立ててるよ!
BootstrapのOSSレポジトリをスキャンしてみる【OSSコードスキャン】
Bootstrapはウェブのフロントエンド開発では最もよく使われているOSSライブラリの一つです。ウェブ開発をやっていればどこの開発チームも使ってそうなBootstrapに対して、脆弱性スキャンをしてみました。
4.Snykから自動作成されたPRを見てみると、自動作成された件名に、脆弱性の中身と修正内容をまとめてくれてるので、PRを承認しやすく、脆弱性管理がかなり簡単になります。(ただ、今回のPRの自動メッセージ作成機能では0.5.2のところが0.5.1になっていたり、まだ不完全なところもあります)
5. 中身はしっかり0.5.2へのアップグレードとなっています。これらをすべて自動でやってくれるのは本当にいいですね!
あとはこのPRをマージすれば脆弱性対応は完了です。ここまで労力が要らないとなると、どの開発チームでも導入しやすく、開発マインドが「Secure by Default」(最初からセキュアに開発していく)に移りやすく、開発チームの底上げになりそうです。
Snykのサポート対応がとてもしっかりしてる
今回の脆弱性検査を行うにあたり、PythonベースのコンテナイメージをCLIからスキャンしようとして、依存の脆弱性を検知できずSnykのサポートを使ってみました。(これは結論として、2021年12月現在でCLIでのPythonベースのイメージスキャンは非対応だからです。ドキュメントでもちゃんと明記してあるので、ちゃんとドキュメントは読みましょう・・・)
本件をSnykサポートで問い合わせしたときの対応とサポートの早さが素晴らしかったです。
Snykでの検査結果と、対象となるレポを共有すると、サポートの方で再現テストを行って下さり、それを元にすぐに開発チームにエスカレーションしてくれました。また、開発チームのレスポンスも迅速でした。ここまでしっかりしてると、実運用でも困らないだろうな、と思います。
以下にサポート内容の一部を共有するので、サポートの良さを見てみて下さい。(個人情報はマスクしてあります)
サマリ
SnykはすでにDocker Scanでデフォルトで使われていたりするように、導入がかなり簡単なのに強力です。
一番大変な脆弱性管理についても、わかりやすい件名をつけてPRを自動作成してくれるので、かなり運用が楽そうですね。
ここまでハードルが低いと、どのサイズの開発チームでも導入しやすく、開発マインドが「Secure by Default」(最初からセキュアに開発していく)にしやすいので、お手軽に開発チームの底上げになりそうです。