SnykとAmazon Inspectorでセキュリティをシフトレフトする
はじめに
はじめまして、CareNetのKazです。
セキュリティはソフトウェア開発の極めて重要な要素である一方、後回しになってしまいがちな要素でもあります。
私が所属するチームではこれまで開発プロセスの最後に第三者によるセキュリティ診断を行うやり方をとっていましたが、以下が問題となっていました。
- 開発プロセスの後半に対応に時間のかかるハイリスクな脆弱性が見つかるとリリーススケジュールに影響を及ぼしてしまう
- セキュリティ診断実施後に登録された新しい脆弱性(プロダクトに含まれるOSSライブラリなどに脆弱性が見つかった場合など)に気付くのが遅れてしまう
これらの問題を解決するため、SnykとAmazon Inspectorを活用して開発プロセスの早い段階でセキュリティ対策を行い、リリース後も継続的に脆弱性監視を行えるようにした取り組みについてご紹介します。
セキュリティツールの選定
上記問題の解決を目指して以下の条件に該当するツールの調査を行った結果、SnykとAmazon Inspectorを利用することにしました。
- 開発運用中のAPIにはRESTとGraphQLのものがあり、その両方の脆弱性を検知できること
- サーバーとして利用しているAWSのEC2、およびECS(で利用するECR)コンテナイメージの脆弱性を検知できること
- 開発中に頻繁にセキュリティスキャンできるように高速&簡単&低コストであること
- AWS CodePipelineで構築しているデプロイパイプラインに組み込めること
- リリース後も新しい脆弱性に該当するかを自動的・継続的に監視できること
Snyk
Snykは包括的なセキュリティプラットフォームです。コード、およびコードが依存するOSSライブラリの脆弱性検出部分は、ソースコードを分析して脆弱性を検出するSAST[1]になります。実行中のアプリケーションに攻撃的なアクセスを行って脆弱性を検出するDASTのツールでは(調査時点では)GraphQL APIの脆弱性を検知できるものを見つけられなかったのに対し、SASTのツールなら検知可能で、その中でも以下の特長を評価しSnykを採用しました。
- IDE(VSCode)用拡張機能があり、開発中にいつでもセキュリティスキャンが行える
- セキュリティスキャンが高速で1回あたり(コード量によると思いますが)1分もかからない
- 脆弱性を解決するためのコード例が確認でき、開発者にとってわかりやすい
- デプロイパイプライン(CodePipeline)への組み込みやGitリポジトリのスキャンが簡単にできる
- 脆弱性だけでなく、重複したコードブロックなどコード品質の問題も検知できる
なお、SnykにはコンテナイメージやIaC(Infrastructure as Code)の脆弱性を検知する機能もあります。詳細は公式をご確認ください。
Amazon Inspector
Amazon InspectorはEC2インスタンス、およびECRコンテナイメージをスキャンし、OSやミドルウェアの脆弱性と意図しないネットワークの露出がないかを検出してくれるAWSサービスです。AWS外のリソースのセキュリティスキャンはできませんが、AWS内であれば簡単に導入にでき、自動的かつ継続的にスキャンできることがメリットです。チームで運用するほぼすべてのサーバーリソースがAWS内にあったため、AWS Inspectorを採用しました。
プルリク時にセキュリティチェックを必須とする
開発プロセスの最後に第三者によるセキュリティ診断を行うやり方から、開発プロセスの全工程で開発者自身がセキュリティ対策を行うやり方に変えるのは簡単なことではなく、ツールを導入するだけでは不十分です。
そこでコードのセキュリティスキャンを行い脆弱性がないことを確認した上でプルリクを出すこと、コードレビューで脆弱性がないと確認できない場合は承認しないこと、というルールを導入し開発中にセキュリティに意識が向くようにしました。脆弱性がない状態を保つのが理想ですが、(特に既存リポジトリで)全ての脆弱性を解決するのは大変で継続のハードルが高くなってしまうと懸念されたため、チームで話し合ってリスクがHigh以上の脆弱性がなければOKというところから開始しました(現在はMiddle以下の脆弱性についても個別評価しリスクが高いと判断した場合はNGとしています)。
プルリク時のセキュリティスキャンはSnykのIDE拡張機能、もしくはSnyk CLIを用いて開発者がローカルで実行します。ローカルでのセキュリティスキャンの実行方法については下記が参考になります。
デプロイパイプラインにセキュリティスキャンを追加する
プルリク時にセキュリティチェックを必須としても、人間が行うことなので漏れやミスによって脆弱性のあるコードをリリースしてしまう可能性は残ります。そこでデプロイパイプラインの中でセキュリティスキャンを行い、リスクHigh以上の脆弱性がある場合はデプロイが中止されるように設定しました。
AWSのCodePipelineのデプロイパイプラインにSnykによるセキュリティスキャンを追加するには、CodePipelineのパイプラインを編集する画面で「ステージを追加する」ボタンをクリックします。
アクションプロバイダーに「Snyk」を選択し、「Snykに接続」ボタンを押します。
Snykの認証後、条件設定を行い、「Continue」ボタンをクリックします。ここで「Block deployment when Snyk finds an error」をチェックすると脆弱性が見つかった場合にデプロイが中止されるようになり、「Block deployment for vulnerabilities with a minimum severity of」でデプロイを中止する脆弱性のリスクレベルを指定することができます。
なお、脆弱性のリスクよりもリリースが遅れることのリスクの方が高い場合など、脆弱性があってもリリースしなければならないことがあります。そのような場合は、Snykの管理画面で対象の脆弱性を無視するように設定することでパイプラインは変更せずにリリースが可能です。脆弱性を無視する場合はその理由を記録し、意図せず無視し続けたままにならないように期限を設定するようにしています。
脆弱性を継続的に監視する
OSやミドルウェア、OSSライブラリの脆弱性は日々新たに発見されており、リリース時にはセキュリティスキャンで脆弱性がない状態だったとしても、リリース後に脆弱性を抱えてしまうことは避けられません。そこでなるべく早期に脆弱性に気付けるように、継続的にセキュリティスキャンを行い、脆弱性が見つかればアラート通知を行う脆弱性監視を導入しました。
コードの脆弱性監視
コードとそこに含まれるOSSライブラリの脆弱性については、SnykでGitHubリポジトリを継続的にセキュリティスキャンすることで監視しました。
Snykの管理画面左サイドメニューの「Projects」を選択し、「Add projects」ボタンを押して「GitHub」を選択します。
GitHubの認証後に脆弱性監視を行いたいリポジトリをチェックし、「Add selected reposiories」ボタンをクリックします。
これだけで継続的にセキュリティスキャンが行われ、脆弱性が見つかるとメールで通知が来るようになります。通知をSlackに送りたい場合は、Snkyの管理画面左サイドメニューの「Integrations」にある「Slack」を選択し、SlackのWebhook URLを登録することで行えます。
サーバーの脆弱性監視
サーバーの脆弱性については、Amazon InspectorでEC2インスタンスとECRコンテナイメージを継続的にセキュリティスキャンすることで監視しました。
EC2インスタンスは、SSM Agentが有効になっていればAmazon Inspectorを有効化するだけで継続的にスキャンが行われるようになります。インスタンスに新しいソフトウェアパッケージがインストールまたはアンインストールされたとき、新しいCVEが公開されたとき、および脆弱なパッケージが更新されたときに自動的にスキャンが行われます。
ECRコンテナイメージは、Agentの有効化等は不要でAmazon Inspectorを有効化するだけで継続的にスキャンが行われるようになります。イメージをECRリポジトリにプッシュしたとき、イメージに影響を与える新しいCVEが公開されたときに自動スキャンが行われます。再スキャンを行う期間は、ライフタイム(イメージが削除されるまで)、180日間、30日間の3つから選べます。
EC2インスタンスのSSM Agentを有効化する方法、およびAmazon Inspectorの脆弱性検出結果をSlackに通知する方法についてはこちらが参考になります。
おわりに
今回は「セキュリティのシフトレフト」を目指したチームの取り組みについてご紹介しました。SnykやAmazon Inspectorのようなツールを活用することで効率的にセキュリティ対策を行うことができます。私たちと同じようなセキュリティの問題を抱えるチームの一助になれば幸いです。
-
SASTとDASTの特徴と違いについてはこちらが参考になります
https://circleci.com/ja/blog/sast-vs-dast-when-to-use-them/ ↩︎
Discussion