Skip to content

ホワイトリストを活用したAWS Lambda上でのCORSやCSRFの対策

Posted on:2022年12月11日

API Gateway と Lambda を実装した際に、とある事情で AWS Lambda 上で CORS の対応を行う必要がありました。
Lambda ではレスポンスヘッダにAccess-Control-Allow-Originの指定が複数できないらしく、そのまま複数の origin を指定することができません。
そのため、Lambda 上でホワイトリストを作成し、問い合わせが来た origin とホワイトリストを比較し、マッチしていれば目的のレスポンスを返すようにします。

ホワイトリストの作成

まずは、ホワイトリストを作成します。 Lambda の環境変数にホワイトリストを設定しましょう。
変数名は任意ですが、今回はWHITELISTとします。
値は、カンマ区切りで複数指定します。

https://example.com,https://example2.com

Lambda の実装

ホワイトリストを作成したら、Lambda の実装を行います。
今回は、Python で実装します。
Python の場合、ホワイトリストを環境変数から取得するには、os.environを使用します。
lambda_handlerは後ほど実装します。

import os

def lambda_handler(event, context):
  // 省略

def is_white_origin(target_origin):
    if not target_origin:
        return False
    origin_whitelist = os.environ["ORIGIN_WHITELIST"].split(",")
    return any(white_origin in target_origin for white_origin in origin_whitelist)

レスポンスヘッダの設定

次に、lambda_handlerにレスポンスヘッダを設定します。 ホワイトリストにマッチしていれば、レスポンスヘッダにAccess-Control-Allow-Originを設定します。

def lambda_handler(event, context):
    // originの取得
    origin = event["headers"]["origin"]
    // ホワイトリストにマッチしていれば、目的のレスポンスを返す
    if is_white_origin(origin):
        response = {
            "statusCode": 200,
            "headers": {
                "Access-Control-Allow-Origin": origin,
                "Access-Control-Allow-Credentials": True,
                "Access-Control-Allow-Headers": "Content-Type Authorization Origin X-Requested-With",
                // その他,必要に応じてヘッダを追加
            },
            "body": json.dumps({"message": "response_message"}),
        }
    else: // ホワイトリストにマッチしていなければ、403を返す
        response = {
            "statusCode": 403,
            "body": json.dumps({"message": "Forbidden"}),
        }
    return response

こちらで実際にレスポンスヘッダにAccess-Control-Allow-Originが設定されていることを確認しましょう。 問題がなければ、これで完了となります。

API Gateway の設定

最後に、API Gateway の設定を行います。
API Gateway のリソースにOPTIONSメソッドを追加し、Lambda のエンドポイントを指定しましょう。

参考記事
https://www.tdi.co.jp/miso/aws-whitelist-api