この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
オープンソースコードやアプリケーションコードの脆弱性診断などができる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
ソースコード
デフォルトのままです。
index.js
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
を追加します。
packaged.json
{
"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(実際に動いている)」に対して、脆弱性診断できるのは便利&嬉しい&助かります。