これは グロービス Advent Calendar 2023 の7日目の記事です。
お気持ち表明
「AWS WAF のルールで Block した上で 200 で返す」と言われてパッとユースケースが思い浮かぶ方はどのくらいいるでしょうか?、割と発想がトリッキーなのでは!?と、
検索しても類似ブログが見当たらないので、他者と被っていないのであれば!と思った次第です。
前提構成
下記のような構成のプロダクトがあるかもしれません(?)
SPA 用ドメイン、とは別に API 用ドメインが用意されている場合、何もしなければ CORS 制限に引っかかります。
実際には Application (Framework)等で CORS 関連の Access Control Header を 付与して Return する事でオリジン間リソース利用可能としている構成を想定してみます。
どういう時に Block しつつ 200 を返したいか?
稀に見る WAF を使った Maintenance Mode で、下記のような時
WAF で社外アクセスを Block した際に Application まで到達せず、普段 Application が付与してる Access Control header が付与されないため、 SPA が Preflight Request 送信時に CORS Error となります。
Cloudfront に Alias で複数ドメイン設定を行っている時
Cloudfront Alias に複数 Domain 付与している時、それぞれの Domain 向けに OPTIONS Request に Return する時に Access-Control-Allow-Origin を * などで一括で大きく許可したくない時です。
MDN 「オリジンを指定します。1 つのオリジンだけを指定することができます。」
設定
- WAF rule 優先度上位で Request Origin && Method で判定し、Custom Response を行う
- Request Origin を条件に入れ、必要ドメイン分 Rule を追加する事で Origin 事の許可ドメインを指定する事が可能です。
resource "aws_wafv2_web_acl" "example" {
name = "example-acl"
description = "example-acl"
scope = "REGIONAL"
default_action {
allow {}
}
# Preflight を 200 return する
rule {
name = "preflight-return"
priority = "0"
action {
block {
custom_response {
response_code = 200
response_header {
name = "Access-Control-Max-Age"
value = "3600"
}
response_header {
name = "Access-Control-Allow-Credentials"
value = "true"
}
response_header {
name = "Access-Control-Allow-Headers"
value = "Origin,Authorization,Accept,Content-Type"
}
response_header {
name = "Access-Control-Allow-Methods"
value = "GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD"
}
response_header {
name = "Access-Control-Allow-Origin"
value = "https://${SUB}.example.com"
}
}
}
}
statement {
and_statement {
statement {
byte_match_statement {
positional_constraint = "EXACTLY"
search_string = "OPTIONS"
field_to_match {
method {}
}
text_transformation {
priority = 0
type = "NONE"
}
}
}
statement {
byte_match_statement {
positional_constraint = "CONTAINS"
search_string = "${SUB}.example.com"
field_to_match {
single_header {
name = "origin"
}
}
text_transformation {
priority = 0
type = "NONE"
}
}
}
}
}
}
}
確認
違和感がすごい(ネーミングと合わせて Preflight Requset を Block するルールの様に見える)
めげずに設定したホストにブラウザアクセスを行うと OPTIONS Request を Server awselb/2.0(正確にはELB Attache WAF) が応答しているのが確認できます。
さいごに
どうにか Origin が存在しない時でも AWS Managed Service 内で OPTIONS Request を捌けないかを考えてる時に閃いた設定です。
技術的には可能です(ただし色々大変)ですとか、技術的には可能です(ただしやって良いとは言ってない)などがあるかもです。
WAF Block request / Allow request 割合監視などを導入している場合、アラート発生となる可能性があります。
ALB 固定レスポンスで同様の事が出来ると良いのですが、現時点(2023.12)では Return Header のカスタマイズが出来ませんでした。
個人的には WAF Block 200 return...! の響き、割と気に入ってます。