はじめに
AWSクラウドで構築されているウェブアプリケーションで、AWS WAFを導入するケースは少なくないだろう。
筆者が所属するチームで運用するアプリケーションでもAWS WAFを導入する事となり、WAFの導入準備から運用開始まで実施する機会があった。
このブログでは、その中で起きたとある事例について紹介したいと思う。
詳しくは後述するが、まずはAWS WAFについての軽い説明から始める。
AWS WAFとは
AWSが提供するウェブアプリケーション保護のファイアウォールで、Amazon CloudFrontやApplication Load Balancer(以下ALB)などにデプロイして使用する。
ルールに基づき、アクセスのブロックや許可を設定する。
ルールは細かくカスタマイズでき、ルールの自作はもちろん、AWSが提供する無料のものやAWS Marketplaceから購入可能なサードパーティー製のものなど、自由に組み合わせて使用することが可能。
WAFの料金体系
Web ACLというアクセスコントロールリストがあり、Web ACLへ紐づいたルールおよびルールグループ毎に利用料金が請求される仕組み。
Web ACLをCloudFrontやALBに紐づけて使用する。
ルール、ルールグループについて
ルールによってリクエストの定義とアクションを決める。
アクションには、Allow、Block、Count、CAPTCHA、Challengeがあり、ルール毎にアクションを指定することができる。
ルールのまとまりがルールグループとなる。
Capacity Units
Web ACLに設定するルールにはCapacity Unitsという制限がある。
各ルールおよびルールグループにはCapacity値があり、Web ACLのCapacity Unitsは1500が上限とされている。
各ルールのCapacity合計が1500以下になるようにルールを選別して組み合わせる。
上限緩和申請でCapacity Unitsを1501以上にすることが可能。
マネージドルール
あらかじめ定義されたルールで、AWSが無料で提供しているルールグループや、サードバーティー製のもの、追加料金がかかるがAWSが提供するAWS WAF Bot Controlなどがある。
また、Bot Controlなど一部を除き、マネージドルールは自動更新され、SNSで更新通知を受け取ることが可能。
AWSマネージドルール
AWSが提供する無料のマネージドルールグループでは、一般的な脆弱性や脅威からアプリケーションを保護するルールや、
SQLやPHPなどのユースケースに対する保護ルールなどが提供されている。
AWS マネージドルールのルールグループのリスト
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups-list.html
ALBのセッションCookieがXSS扱いされる
冒頭で触れた事例について紹介していく。
AWS WAFの導入後、Blockされたリクエストの調査を行う中で、クロスサイトスクリプティング(以下XSS)として扱われBlockされたリクエストがいくつかあった。
調べていくと、ALBのスティッキーセッション機能によって生成されるCookieが原因であることがわかった。
発生した事象
2023年3月現在、AWSマネージドルールとしてAWSより提供されているコアルールセットの最新バージョンは1.5だが、
少なくともVer.1.4では、CrossSiteScripting_COOKIEルールでALBの発行するセッションCookieがXSSと見なされ、Blockされるという事象が発生する。
検知されたリクエストは、WAFのログに以下の様に出力される。
1件のリクエストに対する1行のログについて、いくつかの項目を抜粋して紹介する。
{"ruleGroupId":"AWS#AWSManagedRulesCommonRuleSet#Version_1.4","terminatingRule":{"ruleId":"CrossSiteScripting_COOKIE","action":"BLOCK","overriddenAction":"BLOCK","ruleMatchDetails":null},"nonTerminatingMatchingRules":[],"excludedRules":null,"customerConfig":null}
AWSManagedRulesCommonRuleSet#Version_1.4、つまり、コアルールセットのVer.1.4で、 CrossSiteScripting_COOKIEというルールでBLOCKされたことがわかる。
"terminatingRuleId":"AWS-AWSManagedRulesCommonRuleSet","terminatingRuleType":"MANAGED_RULE_GROUP","action":"BLOCK","terminatingRuleMatchDetails":[{"conditionType":"XSS","location":"HEADER","matchedData":["OndMA","=;"]}]
マッチしたデータは、"matchedData":["OndMA","=;"]
らしいので、リクエストの中身を見てみる。
httpRequestのheadersの内容を確認すると、cookieのデータに前述のmatchData
に該当するものがあった。
key=value形式で出力されたcookieの情報のvalueの末尾付近に、matchData
の"OndMA"が含まれている。
AWSALB=DjoBw0yrLRQVQZjsJTrYTocU6cagnx24lNymUD2nIaJuybCtCvTYds/DIKGtD3boTBoParRo3Pza5JtUxN6E8hJBvpU/16D/VgS2w8ZYYL/UtLkh9XZaUJRLzGHpcRSXdeoq6zH8VpuQESkUOtAzWt4yGEtSnBytSeZl1L7RJA4jel5sxwW+ITRZ+OndMA== AWSALBCORS=DjoBw0yrLRQVQZjsJTrYTocU6cagnx24lNymUD2nIaJuybCtCvTYds/DIKGtD3boTBoParRo3Pza5JtUxN6E8hJBvpU/16D/VgS2w8ZYYL/UtLkh9XZaUJRLzGHpcRSXdeoq6zH8VpuQESkUOtAzWt4yGEtSnBytSeZl1L7RJA4jel5sxwW+ITRZ+OndMA==
keyには、『AWSALB』とある。 以上の事から、AWSのALBが生成するセッションCookieの値の末尾に「=」が含まれたため、リクエストがXSSとみなされBlockされたことがわかる。
回避方法
ここからは、前述した事象を回避する方法を紹介する。
CrossSiteScripting_COOKIEをCountに
まずは、AWS-AWSManagedRulesCommonRuleSetで、CrossSiteScripting_COOKIEをBlockからCountに変更する。
そうすると、ルールに引っかかった場合はBlockされないが、該当するリクエストには『CrossSiteScripting_COOKIE』というラベルが貼られる。
ラベルによって、CrossSiteScripting_COOKIEに該当したリクエストを、別のルールで評価することができるようになる。
CrossSiteScripting_COOKIE に該当したリクエストを検査するルールを追加
次に、CrossSiteScripting_COOKIEというラベルを持つリクエストに対し、ALBが発行したCookieかどうかを検査し、ALB発行でないCookieの場合にBlockするルールを追加する。
以下の様に設定していく。
- AWS Management ConsoleにサインインしAWS WAFコンソールを開き下記内容を設定
- Web ACLsからルールを追加したいACLを選択する
- [Add Rule] (ルールの追加) 、[Add my own rules and rule groups] を選択する
- Rule
- [Name] : 任意の名前
- [Type] : Regular rule
- Rule
- [If a request] で [matches all the statements (AND)] を選択する
- Statement 1 では下記の様に設定する
- Negate statement (NOT)
- [Negate statement results] : チェックしない
- [Inspect] : Has a label
- Labels
- [Match scope] : Label
- [Match key] : awswaf:managed:aws:core-rule-set:CrossSiteScripting_Cookie
- Negate statement (NOT)
- Statement 2 では下記の様に設定する
- Negate statement (NOT)
- [Negate statement results] : チェックする
- [Inspect] : Cookies
- [Cookies match scope] : Keys
- [Content to inspect] : All cookies
- [Match type] : Matches regular expression
- [Regular expression] : AWSALB(|CORS|TG|TGCORS|APP-[0-3])=.+
- [Text transformation] : None
- [Oversize handling] : Continue
- Negate statement (NOT)
- Then では下記の様に設定する
- [Action]:Block
さいごに
AWS WAFでAWSのマネージドルールを使用するケースは多いと思う。
AWSのマネージドルールでALBのCookieがBlockの要因になるとは驚きだが、AWS WAFは独自のルールを細かく設定できるため、たとえルール自体に問題があっても、ラベルなどを利用しうまく回避することができる。
新しいルールを作成した場合などは、必ずWeb ACLへの変更を事前にテストし、意図しないブロックを発生させないようにしよう。