Snyk でデプロイ済みの AWS Lambda の脆弱性診断をしてみた
オープンソースコードやアプリケーションコードの脆弱性診断などができるSnyk(スニーク)があります。 Snykでは様々なことができますが、本記事では、デプロイ済みのAWS Lambdaに対する脆弱性診断を試してみました。 デプロイ済みのAWS Lambdaに対して脆弱性診断ができるので、下記が不要です(もちろん対応してもOKです)。
- 新たにCI/CDを構築して、脆弱性診断を導入する
- 既存のCI/CDに脆弱性診断を導入する
- AWS Lambdaコードを取得して、ローカルPCなどで脆弱性診断を行う
- など
CI/CDの脆弱性診断はPASSしたけど、「デプロイする直前で脆弱性が入る」「デプロイ済みのコードに脆弱性が入る」という可能性もゼロではありません。 また、多く使われているライブラリに脆弱性が発見されたとき、「今動いているLambdaで使われているのか?」も気になるところです。 そのため、「デプロイ済みのLambda(実際に動いている)」に対して、脆弱性診断できるのは便利&嬉しい&助かります。
なお、本記事は、Snyk Advent Calendar 2021の11日目となります。 Snykの特徴や機能などをたくさん知ることができるので、他の記事もぜひご覧ください。
おすすめの方
- Snykについてざっくり知りたい方
- デプロイ済みのAWS Lambdaに対して、脆弱性診断を行いたい方
Snyk(スニーク)は、デベロッパーファーストのセキュリティプラットフォーム
Snykについては、中の人が書かれた下記の記事が、まずおすすめです。
Snykには、下記の製品とツールがあります。できること・方法の全体像が見えてきますね。
Snykの製品
・Snyk Open Source: オープンソースコードの脆弱性を発見し、修正することができます。
・Snyk Code: アプリケーションコードの脆弱性を発見し、修正することができます。
・Snyk License Compliance Management: オープンソースのライセンス問題の発見と修正
・Snyk Container: コンテナイメージの脆弱性を発見し、修正することができます。
・Snyk Infrastructure as Code: Kubernetes、Helm、Terraformの設定ファイルの脆弱性を発見し、修正します。
・Snyk Intel Vulnerability Database: オープンソースやコンテナにおける、包括的で実践的な脆弱性に関するデータにアクセスできます。Snykのツール
・Snyk.io: ウェブベースのUI
・Snyk CLI: コマンドラインのインターフェース
・Snyk API: Snykとの統合をプログラムで行うことができますhttps://qiita.com/SnykSec/items/aa80a976eb17299fff62
Snykは、さまざまな開発言語・パッケージマネージャーをサポートしています。詳細は下記をご覧ください。
AWS Lambdaに対する脆弱診断の概要
概要
IAMロール(Snyk用)を準備し、AWSアカウント(Snyk)が情報取得して診断する仕組みのようです。
対応言語
本記事の作成時点で、「AWS Lambda統合」は下記の言語に対応しています。
- Node.js
- Ruby
- Java
AWS Lambda integration - Snyk User Docs
診断対象
AWS Lambdaにデプロイされたアプリケーションコードではなく、パッケージマネージャーが診断対象のようです。
診断対象のAWS Lambdaを作成する
それでは、やっていきましょう。
sam init
sam init \ --runtime nodejs14.x \ --name snyk-test-sample \ --app-template hello-world \ --package-type Zip
ソースコード
デフォルトのままです。
let response; exports.lambdaHandler = async (event, context) => { try { response = { 'statusCode': 200, 'body': JSON.stringify({ message: 'hello world', }) } } catch (err) { console.log(err); return err; } return response };
packaged.json
利用ライブラリとして、axios
があります。
{ "name": "hello_world", "version": "1.0.0", "description": "hello world sample for NodeJS", "main": "app.js", "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", "author": "SAM CLI", "license": "MIT", "dependencies": { "axios": "^0.21.1" }, "scripts": { "test": "mocha tests/unit/" }, "devDependencies": { "chai": "^4.2.0", "mocha": "^8.2.1" } }
デプロイ
sam build sam package \ --output-template-file packaged.yaml \ --s3-bucket cm-fujii.genki-deploy sam deploy \ --template-file packaged.yaml \ --stack-name snyk-test-sample-stack \ --s3-bucket cm-fujii.genki-deploy \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
Snykのアカウントを作成し、Organization IDを取得する
Snykにアクセスし、アカウントを作成します。 その後、右上のセッティングを選択します。
Organization ID
が表示されるので、コピーしておきます。
AWSとSnykを連携する
「Snyk と AWS Lambda との統合」をデプロイする(Snyk用のIAMロールを作成する)
下記にアクセスします。
「デプロイ方法」のタブを選択し、「Snyk と AWS Lambda との統合」を選択します。 実態としては、Snyk用のIAMロールを作成します。
CloudFormationが開くので、そのままデプロイしていきます。
3つのパラメータ入力を求められるので、入力します。
name | value |
---|---|
Snyk organization ID | Snyk organization ID |
Snyk AWS Account ID | 198361731867 |
Lambda Resource ARN | * |
「Snyk AWS Account ID」は、Snykのドキュメントに記載があります。
スタックの作成を実行し、完了するまで待ちます。 デプロイ完了後、作成されたIAMロールのARNをコピーしておきます。
Snyk用のIAMロールをSnykに設定する
Snyk上部の「integrations」を選択し、「AWS Lambda」を選択します。
続けて、先ほど作成したIAMロールのARNを入力してSaveします。
接続成功しました!!!
接続失敗する場合は、数分ほど待ってから再設定を試してください。
おまけ: 作成されたAWSリソースを確認する
IAMロールが1つ作られました。
Lambda情報を参照する権限を持っていました。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "lambda:ListFunctions", "lambda:GetAccountSettings" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "lambda:GetFunction", "lambda:ListAliases" ], "Resource": [ "*" ], "Effect": "Allow" } ] }
AWS Lambdaの脆弱性を診断する
診断するAWS Lambdaを追加する
あらためて、Snyk上部の「integrations」から「AWS Lambda」を選択します。
AWS Lambdaの一覧が表示されるため、先ほど作成したAWS Lambdaを選択します。
「失敗した」と表示されますが、実際は成功しているようです。
問題ないようですね。
AWS Lambdaのライブラリを更新する
packaged.json
のdependencies
に約4年前のバージョンのaws-sdk
を追加します。
{ "name": "hello_world", "version": "1.0.0", "description": "hello world sample for NodeJS", "main": "app.js", "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs", "author": "SAM CLI", "license": "MIT", "dependencies": { "axios": "^0.21.1", "aws-sdk": "2.183.0" }, "scripts": { "test": "mocha tests/unit/" }, "devDependencies": { "chai": "^4.2.0", "mocha": "^8.2.1" } }
デプロイします。
sam build sam package \ --output-template-file packaged.yaml \ --s3-bucket cm-fujii.genki-deploy sam deploy \ --template-file packaged.yaml \ --stack-name snyk-test-sample-stack \ --s3-bucket cm-fujii.genki-deploy \ --capabilities CAPABILITY_NAMED_IAM \ --no-fail-on-empty-changeset
再診断を行うと、アラートが出た!
「Retest now」を押します。
アラートが出ました!!
- CWE - CWE-400: Uncontrolled Resource Consumption (4.6)
- CVE - CVE-2020-28472
- Common Vulnerability Scoring System Version 3.1 Calculator
- Prototype Pollution in aws-sdk | Snyk
提示されたリンクに飛ぶと、解決策がありました。便利ですね。
様子を見てみる
issuesの数や依存しているライブラリも表示されました。
脆弱性診断の履歴も見れました。
通知やチェック頻度も設定できるようです。
さいごに
AWSにデプロイ済みのLambdaに対して、Snykで脆弱診断を試してみました。 言語などの条件はありますが、未更新で放置されているLambdaなどに対して、コード取得する手間やCI/CDを作って脆弱性診断を導入する手間が無いのが嬉しいです。
CI/CDの脆弱性診断はPASSしたけど、「デプロイする直前で脆弱性が入る」「デプロイ済みのコードに脆弱性が入る」という可能性もゼロではありません。やはり、「デプロイ済みのLambda(実際に動いている)」に対して、脆弱性診断できるのは便利&嬉しい&助かります。