AWS WAF で検査対象のコンポーネントで複数ヘッダーを対象にすることが出来るようになりました

2022.06.22

いわさです。

AWS WAFではHTTPヘッダーを対象に検査が出来ますが、複数ヘッダーに対して一括で検査することが出来るようになりました。

ただし、2022年6月21日のアップデートになっていますが、ドキュメント履歴を見る限りでは、2022年4月29日ごろには実装されていたようです。
実際に、私もこの記事に記載されているAll headersについては以前目にしたようなしてないような...という感じでした。

追加されたもの

対象のコンポーネントに「All headers」が指定出来るようになったようです。
共通のルールを定義したい場合、個別のヘッダー名を指定して複数のルールを作成しなくて良くなりました。

また、少しオプションが用意されています。
今回の記事で少し検証したいと思いますが、全てのヘッダーとしつつも検査対象ヘッダーを絞り込んだり、上限に達した場合にどういう扱いにするかを指定することが出来ます。

大きなポイントとしては上記かなと思いますが、個別の設定項目詳細は以下をご確認ください。

試してみる

適当な API Gateway を作成し、ACLをアタッチさせていくつか確認してみたいと思います。
ちなみに、API Gatewayに直接アタッチする場合はエッジ最適化で構成する必要があります。

まずは、全てのヘッダーを対象に、hogeという文字列が含まれていたら、ブロックしつつカスタムレスポンスでWAF Blockedというメッセージを表示するようにしたいと思います。

まずは適当なヘッダーに禁止文字列を設定する場合としない場合を試してみましょう。超正常系です。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: iwasa"  
203.0.113.1

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: hoge"
WAF Blocked

期待どおりブロックされました。
ヘッダー名を指定せずとも、全ヘッダーを検査してくれていますね。

対象ヘッダーを絞りこむ

次に、All Headersとしつつ、複数のヘッダーキーに対象を絞り込んでみます。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: iwasa" \
-H "x-iwasa-header3: hoge"
203.0.113.1
$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: hoge" \ 
-H "x-iwasa-header3: iwasa"
WAF Blocked%

お、Includeとして指定したヘッダー以外に禁止文字列を設定しても無視されました。なるほど。
対象ヘッダーが複数の場合はSingle Headerのルールを複数作成せずに、All HeadersでIncludeで明示してあげるのが良さそうですね。

このExcluded headersとIncluded headersは、ドキュメントでは以下の記述があります。

ここで指定した文字列のいずれかに一致するキーを持つヘッダーのみを検査します。キーの文字列一致は大文字と小文字が区別され、完全に一致する必要があります。

これを試してみます。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "X-IWASA-HEADER2: hoge" \
-H "x-iwasa-header3: iwasa"
WAF Blocked%
$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: iwasa" \
-H "x-iwasa-header22: hoge" 
203.0.113.1

完全一致ではありますが、大文字と小文字は区別されていないように見えますね。
HTTP2でヘッダーの大文字小文字の仕様が変わってた気がするのでバージョンを指定してみましたが、以下のように区別されずにブロックされていました。

ちなみに、検査値については大文字小文字は区別されていました。
以下の場合はブロックされません。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "X-IWASA-HEADER2: HOGE" \
-H "x-iwasa-header3: iwasa"
203.0.113.1

Oversize handlingを試してみる

Oversize handlingではWAFの上限を超えた場合に検査の扱いをどうするのか決めることが出来ます。
ドキュメントでは以下のように定義されています。

検査できるのは、最大で、リクエストヘッダーの最初の 8 KB (8,192 バイト) かつ、最初の 200 ヘッダーです。

この時に以下を選択することが出来ます。

  • 制限に達するまで検査する
  • 検査せずに一致すると判断する
  • 検査せずに一致しないと判断する

ここでは、「検査せずに一致すると判断する」を指定して試してみます。
推測が正しければ、201ヘッダー以上の場合であればhogeが含まれていなくてもブロックされるはず。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: iwasa" \

:

-H "x-iwasa-header200: iwasa" \
-H "x-iwasa-header201: iwasa" \
-H "x-iwasa-header202: iwasa" \
-H "x-iwasa-header203: iwasa" \
-H "x-iwasa-header204: iwasa" \
-H "x-iwasa-header205: iwasa"
WAF Blocked

余裕もたせて205でやってみたのですが、ブロックされましたね!

そして、この検証をしているときに気がついたのですが、このヘッダー数の制限は、Include headers / Exclude headers の設定でフィルタリングされたあとのヘッダーが対象となっていることに気が付きました。
つまり、205ヘッダーを送信している状態でも、Include headers設定で検査対象ヘッダーが200以下であれば、通常どおり検査されるということです。

先程ブロックされたものと同じリクエストを以下の設定で試してみましょう。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: iwasa" \
-H "x-iwasa-header2: iwasa" \

:

-H "x-iwasa-header202: iwasa" \
-H "x-iwasa-header203: iwasa" \
-H "x-iwasa-header204: iwasa" \
-H "x-iwasa-header205: iwasa"
203.0.113.1

今度はブロックされずに通過しましたね。
対象にしているx-iwasa-header1に禁止文字を設定してみます。

$ curl https://gf858ct8i6.execute-api.us-east-1.amazonaws.com/hoge \
-H "x-iwasa-header1: hoge" \
-H "x-iwasa-header2: iwasa" \
-H "x-iwasa-header3: iwasa" \

:

-H "x-iwasa-header202: iwasa" \
-H "x-iwasa-header203: iwasa" \
-H "x-iwasa-header204: iwasa" \
-H "x-iwasa-header205: iwasa"
WAF Blocked

ブロックされました。
これは上限超過での一致ではなく、文字列での一致が動いていますね。

さいごに

本日は、AWS WAF で複数ヘッダーを対象とした検査機能を試してみました。
今まで複数のヘッダーに共通の制限を行いたい場合に、複数ルールを作成していた場合は今回の機能を使って対象ヘッダーを複数指定することでひとつのルールに出来そうですね。