[アップデート] AWS WAF で Header Order リクエストコンポーネントが追加されました

2023.06.05

いわさです。

AWS WAF のカスタムルールではヘッダー、クッキー、クエリ文字列、ボディなど様々なフィールドに対して検査を行うためのリクエストコンポーネントというものが提供されています。

先日のアップデートで、このリクエストコンポーネントに Header Order というものが追加されていました。

AWS 公式のアップデートアナウンスがまだ無いので手探りで検証してみてどうにか動いたので、何が出来るのかを紹介したいと思います。

(2023.06.06 追記)公式アナウンスも出ました。

リクエストヘッダーをコロンで結合した文字列が検査対象になる

今回は API Gateway の適当なステージに Web ACL をアタッチした場合のリクエストでテストしてみます。
ひとまず、今回追加された Header Order を使ったルールに該当しない場合は全部ブロックさせるルールになっています。

普通に cURL で API へアクセスしてみるとブロックされます。

% curl "https://---/hoge/" -H "header1:hoge1" -H "header2:hoge2"
{"message":"Forbidden"}

上記のようにブロックされた際に AWS WAF 側のログやコンソールで確認出来るリクエスト内容は次のようになっています。

上記リクエストに対して、リクエストコンポーネントは次のようにヘッダーキーをリクエスト時に送信された順序で文字列結合し、検査用の文字列を生成します。

X-Forwarded-For:X-Forwarded-Proto:X-Forwarded-Port:Host:X-Amzn-Trace-Id:user-agent:accept:header1:header2

そのため、上記の検査用文字列をルール側で次のように設定すると、先程のリクエストと完全に一致することになります。

% curl "https://---/hoge/" -H "header1:aaa" -H "header2:bbb"
hoge succress

また、リクエストヘッダーの順序を結合した文字列が作成されるので、次のようにヘッダー順序を入れ替えるとブロックされました。なるほど。

% curl "https://---/hoge/" -H "header2:aaa" -H "header1:bbb"
{"message":"Forbidden"}

Contains string でカスタムヘッダーの順序のみ検査

Match Type が Exactly matches string の場合は API Gateway 側で自動で設定されるヘッダーなども全て対象にする必要があります。
もし、カスタムヘッダーの順序だけを検査したい場合は次のように設定することも出来ます。

ここでは上記のように 3 つのカスタムヘッダーを設定しました。
次のようにカスタムヘッダーの順序が評価されていることがわかります。

% curl "https://---/hoge/" -H "hoge1:aaa" -H "hoge2:bbb" -H "hoge3:ccc"
hoge succress
% curl "https://---/hoge/" -H "hoge1:aaa" -H "hoge3:ccc" -H "hoge2:bbb"
{"message":"Forbidden"}

大文字・小文字は区別されていそう

公式ドキュメントには「Matches that AWS WAF performs against the header order string are case insensitive.」と記述されていましたが、私のほうで検証した限りでは区別されているように見えました。

API Gateway のリージョナル REST API では HTTP 2 がサポートされています。
ここでは HTTP 1.1 と HTTP 2 でヘッダー大文字小文字の問題があるので、気をつけながら確認してみます。

ルールが小文字の場合

次のように HTTP 1.1 で大文字を指定した場合はブロックされています。
一方で HTTP 2 で大文字ヘッダーを指定した場合は許可されています。

% curl "https://---/hoge/" -H "hoge1:aaa" -H "hoge2:bbb" -H "hoge3:ccc" --http1.1
hoge succress
% curl "https://---/hoge/" -H "HOGE1:aaa" -H "HOGE2:bbb" -H "HOGE3:ccc" --http1.1
{"message":"Forbidden"}
% curl "https://---/hoge/" -H "HOGE1:aaa" -H "HOGE2:bbb" -H "HOGE3:ccc" --http2  
hoge succress

ルールが大文字の場合

次のように HTTP 1.1 で大文字ヘッダーを指定した場合のみアクセスが許可されました。

% curl "https://---/hoge/" -H "HOGE1:aaa" -H "HOGE2:bbb" -H "HOGE3:ccc" --http2  
{"message":"Forbidden"}
% curl "https://---/hoge/" -H "HOGE1:aaa" -H "HOGE2:bbb" -H "HOGE3:ccc" --http1.1
hoge succress
% curl "https://---/hoge/" -H "hoge1:aaa" -H "hoge2:bbb" -H "hoge3:ccc" --http1.1
{"message":"Forbidden"}

さいごに

本日は AWS WAF で Header Order リクエストコンポーネントが追加されたので試してみました。

AWS API のドキュメントなどでは公開当初は「カンマ区切り」とされていたのですが、「コロン区切り」が正しいです。古い AWS CLI のリファレンスとか確認している場合はご注意ください。

ユースケースとしては、少し前に CloudFront で利用可能になったリクエスト偽装検出のための次のアップデートを、AWS WAF 単体で実現出来るようにするものなのかなと推察してます。