[Tips] AWS WAF を紐付けた API Gateway で 10KB を超えるリクエストを送信できない

#はじめに

AWS CDK で構築していた [API Gateway](https://aws.amazon.com/jp/api-gateway/) で一定サイズ以上のリクエストボディを指定して API を呼び出したときに、そのリクエストに対するレスポンスが常に `403` になる問題に遭遇しました。

具体的には `"x-amzn-ErrorType" = "ForbiddenException"` というレスポンスヘッダと共に `403` が返却されていました。[リンク先](https://aws.amazon.com/jp/premiumsupport/knowledge-center/api-gateway-troubleshoot-403-forbidden/)の `フィルタリングされた AWS WAF` の項目に該当します。

上記の問題は、**何も考えずに [WAF](https://aws.amazon.com/jp/waf/) を設定していたことに起因していました。**本記事ではその解決方法について簡単にまとめたものになります。

#コアルールセットからリクエストボディ制限に関するルールを除外する

API Gateway に紐づけていた WAF の設定に `AWSManagedRulesCommonRuleSet` がありました。下記の通り、`AWSManagedRulesCommonRuleSet` については [AWS 公式でも設定が推奨されている](https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-list.html#aws-managed-rule-groups-baseline)ような文言があったためです。 

> すべての AWS WAF ユースケースでこのルールグループを使用することを検討してください。

設定しておくことで [OWASP](https://www.ntt.com/bizon/glossary/e-o/owasp.html) が公表している一般的な脆弱性に対処可能になリます。しかし、**`AWSManagedRulesCommonRuleSet` には `SizeRestrictions_BODY` というルールが設定されているため、10KB 以上のリクエストボディを指定したリクエストが送信不可になります。**

今回は API Gateway でファイルを添付して利用する API を構築していました。そのため、今回のプロジェクトでは `SizeRestrictions_BODY` というルールだけ除外したいと考えました。そこで調査したところ、**AWS WAF には特定のルールのみ例外が設定可能なことを[この記事](https://aws.amazon.com/jp/about-aws/whats-new/2018/12/announcing-rule-group-exception-for-managed-rules-for-aws-waf/)で知りました。**

そこで AWS CDK で構築した AWS WAF の定義を下記の変更を加えました。

```typescript
//...
new wafv2.CfnWebACL(root, `${projectName}-web-acl`, {
  defaultAction: { allow: {} },
  scope: "REGIONAL",
  visibilityConfig: {
    cloudWatchMetricsEnabled: true,
    sampledRequestsEnabled: true,
    metricName: "websiteWafV2WebAcl",
  },
  rules: [
    {
      name: "AWSManagedRulesCommonRuleSet",
      priority: 1,
      statement: {
        managedRuleGroupStatement: {
          vendorName: "AWS",
          name: "AWSManagedRulesCommonRuleSet",
          // 追記箇所: リクエストボディの制限に関するルールのみ除外する
          excludedRules: [
            { name: "SizeRestrictions_BODY" }
          ]
        },
      },
      overrideAction: { none: {} },
      visibilityConfig: {
        cloudWatchMetricsEnabled: true,
        sampledRequestsEnabled: true,
        metricName: "AWSManagedRulesCommonRuleSet",
      },
    },
  ],
});
//...
```

**[ExcludedRule](https://docs.aws.amazon.com/waf/latest/APIReference/API_ExcludedRule.html) を指定することで特定のルールのオプションを `Block` から `Count` に変更することが可能です。**[詳細はこちら](https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-rule-action.html)

これで、10KB 以上のリクエストボディを指定して `SizeRestrictions_BODY` のルールに引っかかってしまっても、AWS WAF + API Gateway の環境でリクエストが通るようになりました。

#おわりに

本記事の内容は、**リクエストボディに関するルールのみならず、他の除外したいルールに対しても同様の変更で対処可能です。**

結局本記事の内容は、ちゃんとドキュメント見て中身を理解して上で　AWS WAF のルールグループを設定しようということだと思うのですが、、失敗を通じて理解できたので良かったです。

本記事の内容がどなたかのお役に立てれば幸いです :sparkle: 

# 参考リンク

- [Amazon API Gateway（規模に応じた API の作成、維持、保護）\| AWS](https://aws.amazon.com/jp/api-gateway/)
- [AWS WAF（ウェブアプリケーションファイアウォール）\| AWS](https://aws.amazon.com/jp/waf/)
- [AWS管理ルールルールグループリスト \- AWS WAF、AWS Firewall Manager、および AWS Shield Advanced](https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-list.html#aws-managed-rule-groups-baseline)
- [OWASPとは？意味・定義 \| ITトレンド用語 \| NTTコミュニケーションズ](https://www.ntt.com/bizon/glossary/e-o/owasp.html)
- [AWS WAF マネージドルールで使用するルールグループの例外の発表](https://aws.amazon.com/jp/about-aws/whats-new/2018/12/announcing-rule-group-exception-for-managed-rules-for-aws-waf/)