API Gateway Rest API StageにおけるAWS WAFの設定について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

今回は、API Gateway REST APIステージで AWS WAF (Web Application Firewall) が関連付けられていない 状態について、そのリスクと対策を解説します。

ポリシーの説明

Amazon API Gateway の Security Hub コントロール – AWS Security Hub

[APIGateway.4] API Gateway は、WAF ウェブ ACL に関連付けられている必要があります

このコントロールは、API Gateway ステージが AWS WAF ウェブアクセスコントロールリスト (ACL) を使用しているかどうかをチェックします。 AWS WAF ウェブ ACL が REST API Gateway ステージにアタッチされていない場合、このコントロールは失敗します。

リスク

Amazon API Gatewayは、APIを公開するためのフルマネージドサービスです。しかし、WAFが関連付けられていない場合、APIは一般的なWeb攻撃に対して脆弱になり、以下のような深刻なセキュリティリスクが発生します。

  • OWASP Top 10の脅威への露出: WAFは、SQLインジェクション、クロスサイトスクリプティング (XSS)、悪意のあるボット、DDoS攻撃、その他の一般的なWeb脆弱性(OWASP Top 10に挙げられるような脅威)からAPIを保護するために不可欠です。WAFがなければ、これらの攻撃はAPI Gatewayを通過し、バックエンドアプリケーションやデータに直接到達する可能性があります。
  • 不正アクセスとデータ漏洩: WAFは、不正なリクエストパターンを検出し、悪意のあるトラフィックをブロックすることで、APIへの不正アクセスを防ぎます。WAFがない場合、攻撃者はブルートフォース攻撃やクレデンシャルスタッフィングなどを試み、認証情報を窃取したり、機密データを不正に取得したりする可能性があります。
  • DDoS攻撃によるサービス停止: WAFは、ボットネットによる大量のリクエストや特定のIPアドレスからの異常なトラフィックパターンを検出し、ブロックすることで、分散型サービス拒否 (DDoS) 攻撃からAPIを保護します。WAFがない場合、DDoS攻撃によってAPIが過負荷になり、正当なユーザーがサービスを利用できなくなる可能性があります。
  • リソースの過剰消費とコスト増: 悪意のあるトラフィックがWAFによってブロックされない場合、それがバックエンドアプリケーションまで到達し、余分な処理リソースを消費する可能性があります。これにより、バックエンドインフラストラクチャのスケーリングが必要になったり、不必要なリソース使用量によってコストが増加したりする可能性があります。

対策

API GatewayのREST APIステージにAWS WAFウェブACLを関連付けることは、APIのセキュリティを大幅に強化し、一般的なWeb攻撃から保護するための非常に重要なベストプラクティスです。

  • ウェブACL (Web ACL) の作成: AWS WAFで、API Gatewayディストリビューションを保護するためのウェブACLを作成します。このウェブACLには、SQLインジェクション、XSS、IPアドレスの評価、レートベースルールなど、一般的な脅威から保護するためのルールを設定します。AWS管理ルールセットの利用を検討してください。
  • API Gatewayステージとの関連付け: 作成したウェブACLを、保護したいAPI Gateway REST APIの特定のステージ(例: prod, dev など)に関連付けます。WAFは、関連付けられたステージへのすべてのリクエストを検査し、設定されたルールに基づいてアクションを実行します。
  • レートベースルールの設定: 特定の期間内にAPIへのリクエスト数が異常に多いIPアドレスを自動的にブロックするレートベースルールを設定することを検討してください。これは、DDoS攻撃やブルートフォース攻撃に対する効果的な防御策となります。
  • IP制限ルールの追加: 特定の国や既知の悪意のあるIPアドレスからのアクセスをブロックするIPセットルールを追加することを検討してください。逆に、管理ネットワークからのアクセスのみを許可したい場合にも利用できます。
  • 監視とアラート: WAFのメトリクス(ブロックされたリクエスト、許可されたリクエストなど)をAmazon CloudWatchで監視し、異常なアクティビティを検知した場合にアラートが発報されるように設定します。これにより、攻撃を早期に把握し、対応できるようになります。
  • 定期的なルールセットのレビューと更新: API GatewayとWAFのルールセットは、新しい脅威やアプリケーションの変更に合わせて定期的にレビューし、更新します。AWS WAFのマネージドルールは、AWSセキュリティチームによって継続的に更新されるため、これを活用することを強く推奨します。

修復方法

AWSコンソールでの修復手順

AWSコンソールを使用して、API Gateway REST APIステージにWAFウェブACLを関連付けます。

前提:

  • 保護したいAPI Gateway REST APIとステージが既に存在していること。
  • AWS WAFで、API Gatewayに関連付けるためのウェブACLが既に作成されていること。ウェブACLのリージョンは、API Gatewayのデプロイリージョンと一致している必要があります。
  1. API Gatewayサービスへ移動: AWSコンソールにログインし、API Gateway サービスを開きます。
  2. REST APIの選択: 左側のナビゲーションペインで「API」の下にある「REST API」を選択し、WAFを関連付けたいREST APIを選択します。
  3. ステージの選択: 左側のナビゲーションペインで「ステージ」を選択し、WAFを関連付けたいステージ(例: prod, devなど)を選択します。
  4. WAFウェブACLの関連付け: ステージの詳細画面の「設定」タブ(または画面下部の「ウェブ ACL」セクション)を見つけます。
    • ウェブ ACL」のドロップダウンメニューから、関連付けたいAWS WAFウェブACLを選択します。「保存」または「変更を保存」をクリックします。 API Gatewayのデプロイが自動的に行われ、WAFウェブACLがステージに関連付けられます。これには数分かかる場合があります。
  5. WAFコンソールでの確認 (オプション): AWS WAFサービスに移動し、関連付けたウェブACLの詳細ページで、「関連付けられた AWS リソース」タブを確認すると、API Gatewayステージがリストされているはずです。

Terraformでの修復手順

TerraformでAPI Gateway REST APIステージにWAFウェブACLを関連付けるには、aws_wafv2_web_acl_association リソースを使用します。

前提:

  • API Gateway REST APIとステージが既にTerraformで定義されているか、データソースとして参照されていること。
  • AWS WAFウェブACLが既にTerraformで定義されているか、データソースとして参照されていること。
# (例) 既存のAPI Gateway REST APIとステージを参照
data "aws_api_gateway_rest_api" "my_api" {
  name = "MyExampleApi" # あなたのAPI Gateway REST API名に置き換え
}

data "aws_api_gateway_stage" "my_api_stage" {
  rest_api_id = data.aws_api_gateway_rest_api.my_api.id
  stage_name  = "prod" # あなたのステージ名に置き換え
}

# (例) 既存のAWS WAFv2 Web ACLを参照
# Web ACLはAPI Gatewayと同一リージョンに作成されている必要があります。
data "aws_wafv2_web_acl" "example_web_acl" {
  name  = "MyApiGatewayWebACL" # あなたのWeb ACL名に置き換え
  scope = "REGIONAL" # API GatewayはREGIONALスコープを使用
}

# API Gateway REST APIステージとWAFウェブACLの関連付け
resource "aws_wafv2_web_acl_association" "api_gateway_waf_association" {
  resource_arn = data.aws_api_gateway_stage.my_api_stage.arn
  web_acl_arn  = data.aws_wafv2_web_acl.example_web_acl.arn
}

# (オプション) もしAPI Gateway REST API、ステージ、WAF Web ACLをTerraformで新規作成する場合の例
/*
# API Gateway REST API
resource "aws_api_gateway_rest_api" "new_api" {
  name        = "NewSecureApi"
  description = "New API protected by WAF"
}

# API Gateway リソースとメソッド、デプロイ、ステージ
resource "aws_api_gateway_resource" "new_api_resource" {
  rest_api_id = aws_api_gateway_rest_api.new_api.id
  parent_id   = aws_api_gateway_rest_api.new_api.root_resource_id
  path_part   = "test"
}

resource "aws_api_gateway_method" "new_api_method" {
  rest_api_id   = aws_api_gateway_rest_api.new_api.id
  resource_id   = aws_api_gateway_resource.new_api_resource.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "new_api_integration" {
  rest_api_id             = aws_api_gateway_rest_api.new_api.id
  resource_id             = aws_api_gateway_resource.new_api_resource.id
  http_method             = aws_api_gateway_method.new_api_method.http_method
  type                    = "MOCK"
  integration_http_method = "GET"
}

resource "aws_api_gateway_deployment" "new_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.new_api.id
  triggers = {
    redeployment = sha1(jsonencode([
      aws_api_gateway_resource.new_api_resource.id,
      aws_api_gateway_method.new_api_method.id,
      aws_api_gateway_integration.new_api_integration.id,
    ]))
  }
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_api_gateway_stage" "new_api_stage" {
  deployment_id = aws_api_gateway_deployment.new_api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.new_api.id
  stage_name    = "prod"
}

# AWS WAFv2 Web ACLの作成例 (REGIONALスコープ)
resource "aws_wafv2_web_acl" "new_web_acl" {
  name        = "NewApiGatewayWebACL"
  scope       = "REGIONAL"
  description = "Web ACL for new API Gateway"
  default_action {
    allow {}
  }
  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "NewApiGatewayWebACL"
    sampled_requests_enabled   = true
  }

  rules {
    name     = "CRSLimitRule"
    priority = 10
    action {
      block {}
    }
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesCommonRuleSet"
        # override_action {
        #   none {}
        # }
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "CRSLimitRule"
      sampled_requests_enabled   = true
    }
  }
  tags = {
    Environment = "Development"
  }
}

# 新規作成したAPI GatewayステージとWAFウェブACLの関連付け
resource "aws_wafv2_web_acl_association" "new_api_gateway_waf_association" {
  resource_arn = aws_api_gateway_stage.new_api_stage.arn
  web_acl_arn  = aws_wafv2_web_acl.new_web_acl.arn
}
*/

上記のTerraformコードでは、aws_wafv2_web_acl_association リソースを使用して、既存のAPI Gatewayステージと既存のAWS WAFウェブACLを関連付けています。

  • resource_arn: API GatewayステージのARNを指定します。これは、data.aws_api_gateway_stage.my_api_stage.arn で取得できます。
  • web_acl_arn: 関連付けるWAFウェブACLのARNを指定します。これは、data.aws_wafv2_web_acl.example_web_acl.arn で取得できます。

コメントアウトされた部分は、もしAPI GatewayやWAFウェブACLをTerraformで新規作成する場合の例です。必要に応じて参考にしてください。

MyExampleApiprodMyApiGatewayWebACL などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、API Gateway REST APIステージにAWS WAFウェブACLを関連付けることの重要性について解説しました。WAFを導入することで、APIを一般的なWeb攻撃から保護し、セキュリティ体制を大幅に強化できます。これは、APIを公開する上での必須のセキュリティ対策と言えるでしょう。

貴社のAPI Gatewayでは、WAFが適切に関連付けられていますか?この機会にぜひ設定を確認・強化してみてください。

こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る