Zenn
🔐

DEF CON 29 で発表された「Alexandre Sieira - Attack Vectors for APIs w AWS API

2025/02/27に公開

はじめに

本記事は、DEF CON 29 Cloud Village で Alexandre Sieira 氏が発表した「Attack Vectors for APIs w AWS API Gateway Lambda Auth」に基づき、API Gateway と Lambda Authorizer を利用する際に陥りがちな設定ミス(特にIAMポリシーのワイルドカード利用)について解説します。

API Gateway と Lambda Authorizer の概要

認証・認可の仕組み

API Gatewayでは、Lambdaを利用して独自の認可機能を実装(このLambdaのことをLambda Authorizerと呼びます)できます。Lambda Authorizerは、クライアントからのリクエストに含まれる認証情報(headers、query、Token等)を元に、IAM Policyを生成して返却します。API Gatewayは返却されたIAM Policyを評価することでエンドポイントのアクセス制御を行います。下記の画像は、この一連の認証・認可全体の流れを示しています(https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html より抜粋)。

API Gatewayの特定のエントリーポイントを許可する例

Lambda Authorizerによって生成されるIAM Policyは以下のような形式となります (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html より抜粋)。

{
  "principalId": "yyyyyyyy", // The principal user identification associated with the token sent by the client.
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}

例えば特定のAPI Gateway(apiId1)におけるprodステージに対しGETメソッドを利用して/product/listというエンドポイントのみを許可する場合は、以下のようなIAM Policyとなります(context及びusageIdentifierKeyは省略)。

{
  "principalId": "user|12345",
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:apiId1/prod/GET/product/list"
      }
    ]
  }
}

3. IAMポリシーとワイルドカードの仕様および注意点

IAMポリシーの基本仕様

IAM Policyは、リソースへのアクセス権限を定義します。リソース指定において、ワイルドカード(*)を利用することで柔軟なマッチングが可能です。

ワイルドカード(*)の挙動

IAMポリシーにおいて/は特別扱いされないため、ワイルドカード * は、/の区切りを超えてマッチングします。このため、作成するIAMポリシーによっては意図しないパスにも一致してしまう可能性があります。

参考: リソース ARN でのワイルドカードの使用

4. 意図しないパスに一致する例

以下のようなAPIエンドポイントに対するカスタム認証を考えます。

管理者用のAPI

  • GET /admin/product/list (商品一覧を取得)
  • PUT /admin/product/{productId} (商品詳細を更新)
  • DELETE /admin/product/{productId} (商品を削除)

一般ユーザ用のAPI

  • GET /product/list (商品一覧を取得)
  • GET /product/{productId} (特定の商品詳細を取得)
  • GET /product/favorites
  • POST /product/{productId}/favorites
  • DELETE /product/{productId}/favorites

誤った許可ポリシーの例

一般ユーザ向けに/product以下のパスに対してどのようなメソッドでも許可するIAMポリシーを返す実装することを考えます。
この時、どのようなメソッド(GET, PUT, DELETE, POSTなど)でのアクセスも許可するために*を利用し以下のようなIAM PolicyをLambaAuthrizerから返却すると、管理者用API用の/admin 以下へのエントリーポイントへの意図しないアクセスを許可しています。
これは管理者用の商品一覧を取得するAPIであれば"arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/prod/GET/admin/product/list"というリソースのパスになるため最初の*/GET/admin/にマッチしてしまいアクセスを許可してしまいます。

{
  "principalId": "user",
  "policyDocument": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/prod/*/product/*"
      }
    ]
  }
}

対策

発表では以下のような対策が示されていました。

限定的なワイルドカード利用の設計

  • ワイルドカードを使用する際は、パスの末尾部分のみを対象とする設計にすることで、不要なパスまでマッチングしないようにします。

明示的なDenyポリシーの導入

  • 特定のリソース(例:/admin/*)に対してDenyルールを明示的に設定することで、意図しないアクセスを防止できます。これはIAM Policyにおいて同一リソースにAllowとDenyが存在する場合、Denyが優先されるためです。

多層防御による認可チェックの強化

  • Lambda Authorizerだけでなく、アプリケーション層など複数のレイヤーで認可チェックを実装することで、セキュリティ対策を強化します。

おわりに

Lambda Authroizerを利用する場合、作成するIAM Policyがどのようなリソースへのアクセスを許可するのかに注意が必要となります。AWSの公式ドキュメント等を参照しつつ、今回紹介しているような観点も踏まえ設計することが大切です。

Cloudbaseでは、noteでも様々な記事を公開しておりますので、ぜひご覧ください。
https://note.com/cloudbase

関連記事・参考URL

Discussion

ログインするとコメントできます