[アップデート]AWS WAFのリクエストボディの検査上限が一部サービスを除き64KBまで引き上げられました
初めに
本日AWS WAFに対してリクエストボディの検査サイズの緩和のアップデートが告知されました。
AWS WAFでは従来リージョナルリソースに対してリクエストボディの検査上限は8KBととなっており、これを超えるリクエストが行われた場合8KBを超える部分に対しては検査がされないという仕様になっていました。
今回のアップデートではこのサイズ上限に緩和が入りデフォルトで16KB、最大で64KBまで検査が行われるようになりより巨大なリクエストに対する検査が可能となります。
なお検査上限は選択式となり16KBを超える値を指定する場合そのサイズを超過したリクエスト数に対して追加の課金が発生します。
対象リソースとしてはALB、AppSyncを除くすべてのリージョナルリソースとなり、ALB、AppSyncに適用している場合は引き続き8KBの制限が適用されます。
なおグローバルリソースであるCloudFrontは本アップデート以前から今回のアップデート相当の仕様となっているため各種リージョナルリソースがこの仕様に追いついたという形となります。
追加料金
https://aws.amazon.com/waf/pricing/?nc1=h_ls
In addition, you will be charged $0.30 per million requests for each additional 16KB analyzed beyond the default body inspection limit. For more information about default limits
新しいデフォルトである16KBまでのチェックであれば追加料金は発生しませんが、それを超えるリクエストのチェックを行った場合はそのリクエスト数に応じ課金が発生します。
費用としては16KB毎に$0.3/100万リクエストの料金となるようです(16KB毎ですので32KB超過(48KBリクエスト)の場合は2カウントの扱い?)。
いくつかのリージョンの料金を確認しましたがリージョン毎の差はないようです。
なお16KBを超えるリクエストが来ると無条件でこの課金が発生する、ということはなく事前にWebACLの設定値でチェックするボディサイズをデフォルト値(16KB)から変更しなければそれ以上のサイズの部分にチェックが発生し追加料金が発生するということはありません。
最新の情報はAWS WAFの料金ページをご参照ください。
設定
作成時もしくは作成後に適用するリソースを選択後設定をすることが可能です。
作成画面のリソース選択画面で最初にリソースがないと特に表示がありませんが
今回拡張対象となる種別のリソースを選択することで検査上限のサイズを選択可能となります。
CloudFrontではリソースが特になくとも設定可能に対しリージョナルリソースがリソース選択後に上限を選択する形になっているのはALB、App Runnerが未対応なためでしょうか。
なお対象としてALB単体を選択するとこのサイズ上限の選択部分が表示されませんが
API Gateway等今回のアップデートの対象となったリソースと同時に選択すると選択部分が表示されます。
注意書きとしてALBとAppSyncは8KBの制限が適用される旨が書かれているため設定値によらず8KBが適用されるという形でしょうか。こちらも後ほど試してみます。
試してみる
コアルールセットを適用した上で新しいデフォルト値である16KBを検査上限としたWebACLを作成します。
コアルールセットにはXSSに対処するためのルールが含まれるためScriptタグを含んだリクエストボディを送信することで検知のチェックを行います。
注意点としてこちらのルールには8KB以上のボディとなるリクエストを検知するSizeRestrictions_BODY
のルールが含まれるのでこちらでブロックされないようにCountに変更しておきます。
AWS WAFの適用先のリソースとしてはAPI Gatewayを指定しておき、そのAPI Gatewayの/helloにpostをするとLambda関数がボディのバイト数を返すようにしておきます。
def lambda_handler(event, context): return { "statusCode": 200, "body": json.dumps({ "message": len(event["body"]) }), }
まずシンプルに単品でScriptタグを送ってみるとブロックされることが確認できます。
念の為ブロック起因を確認しましたがAWS#AWSManagedRulesCommonRuleSet#CrossSiteScripting_BODY
でBLOCKが発生しているので想定通りです。
% curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d '<script>' {"message":"Forbidden"} ## 適当な文字列ではそのバイト数が返ってくる % curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d 'aaaaa' {"message": 5}%
16KBを超えるように16384バイト分適当な文字を詰めてその後にScriptタグを詰めた場合は検出されなくなりますが、旧上限値である8KBを超えたラインでは検出されることが確認できます。
## 16KB超過チェック % echo `printf "0%.0s" {0..16383}` > large.txt % curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d @large.txt {"message": 16384}% % echo "<script>" >> large.txt % curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d @large.txt {"message": 16392}% ## 8KB超過チェック %echo `printf "0%.0s" {0..8195}` > large.txt % curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d @large.txt {"message": 8196}% % echo "<script>" >> large.txt % curl https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello -X POST -d @large.txt {"message":"Forbidden"}%
上記の16KBを設定したWAFを同時にALBにも割り当ててみましたが指定した16KBの設定は無視され従来の8KBまでのチェックとなりました。
% echo "<script>" > large.txt % curl http://waf-attach-test-xxxxxx.ap-northeast-1.elb.amazonaws.com -X POST -d @large.txt <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> </body> </html> ## ALBの裏のリソースを用意していないので502ですがWAFでブロックされていれば上記のように403となるためWAFのチェックは突破しています % echo `printf "0%.0s" {0..8195}` > large.txt % echo "<script>" >> large.txt % curl http://waf-attach-test-xxxxxx.ap-northeast-1.elb.amazonaws.com -X POST -d @large.txt <html> <head><title>502 Bad Gateway</title></head> <body> <center><h1>502 Bad Gateway</h1></center> </body> </html>
終わりに
WAFがより広い範囲の検査を行えるようになったことにより広く保護ができるようになりました。
効いてきそうな対象のイメージとしてはCMS機能で大きな文字列をPOSTするような場合やCSV等少し大きめのテキストベースのファイルを管理機能で取り扱うような場合でしょうか。
取り扱えるリソース種別としてはかなり広くなりましたが特に多く使われている印象のあるALBが引き続き8KBとなっているのでこちらの対応が待ち遠しいところです。