Snyk でデプロイ済みの AWS Lambda の脆弱性診断をしてみた

デプロイ済みのAWS Lambdaも脆弱性診断ができます。そう、Snykならね。
2021.12.11

オープンソースコードやアプリケーションコードの脆弱性診断などができる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)が情報取得して診断する仕組みのようです。

SnykがAWS Lambdaの脆弱性を診断する仕組み

対応言語

本記事の作成時点で、「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にアクセスし、アカウントを作成します。 その後、右上のセッティングを選択します。

Snykの設定ボタン

Organization IDが表示されるので、コピーしておきます。

Organization IDをコピーする

AWSとSnykを連携する

「Snyk と AWS Lambda との統合」をデプロイする(Snyk用のIAMロールを作成する)

下記にアクセスします。

「デプロイ方法」のタブを選択し、「Snyk と AWS Lambda との統合」を選択します。 実態としては、Snyk用のIAMロールを作成します。

SnykとAWS Lambdaを統合する

CloudFormationが開くので、そのままデプロイしていきます。

CloudFormationの実行を進める

3つのパラメータ入力を求められるので、入力します。

name value
Snyk organization ID Snyk organization ID
Snyk AWS Account ID 198361731867
Lambda Resource ARN *

パラメータを入力する

「Snyk AWS Account ID」は、Snykのドキュメントに記載があります。

SnykのAWSアカウントIDの記載場所

スタックの作成を実行し、完了するまで待ちます。 デプロイ完了後、作成されたIAMロールのARNをコピーしておきます。

Snyk用のIAMロールが作られた

Snyk用のIAMロールをSnykに設定する

Snyk上部の「integrations」を選択し、「AWS Lambda」を選択します。

SnykとAWS Lambda統合の設定を開始する

続けて、先ほど作成したIAMロールのARNを入力してSaveします。

Snyk用のIAMロールのARNを入力する

接続成功しました!!!

SnykとAWS Lambda統合が成功した

接続失敗する場合は、数分ほど待ってから再設定を試してください。

おまけ: 作成されたAWSリソースを確認する

IAMロールが1つ作られました。

Snyk用のIAMロールができた

Snyk用のIAMロールの様子

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」を選択します。

SnykとAWS Lambda統合する

AWS Lambdaの一覧が表示されるため、先ほど作成したAWS Lambdaを選択します。

Lambdaを選択する

Lambdaを決定する

「失敗した」と表示されますが、実際は成功しているようです。

SnykとAWS Lambda統合が成功する

問題ないようですね。

脆弱性診断の結果(問題なし)

AWS Lambdaのライブラリを更新する

packaged.jsondependenciesに約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」を押します。

Retestする

アラートが出ました!!

ライブラリに脆弱性が見つかった

見つかった脆弱性の詳細

提示されたリンクに飛ぶと、解決策がありました。便利ですね。

見つかった脆弱性の詳細と修正方法

様子を見てみる

issuesの数や依存しているライブラリも表示されました。

依存ライブラリも見れる

脆弱性診断の履歴も見れました。

脆弱性診断の履歴も見れる

通知やチェック頻度も設定できるようです。

通知設定や脆弱性診断の頻度などが設定できる

さいごに

AWSにデプロイ済みのLambdaに対して、Snykで脆弱診断を試してみました。 言語などの条件はありますが、未更新で放置されているLambdaなどに対して、コード取得する手間やCI/CDを作って脆弱性診断を導入する手間が無いのが嬉しいです。

CI/CDの脆弱性診断はPASSしたけど、「デプロイする直前で脆弱性が入る」「デプロイ済みのコードに脆弱性が入る」という可能性もゼロではありません。やはり、「デプロイ済みのLambda(実際に動いている)」に対して、脆弱性診断できるのは便利&嬉しい&助かります。

参考