WebサイトにAWS WAFを適用した際、マネージドルールによる誤検知が発生することがあります。
そのような場合の対策の一つとして、特定の条件に該当するリクエストをマネージドルールの検査対象から除外する方法があります。
本記事では、特定のURIを除外するケースを例に、その実装方法をご紹介します。
本記事の手順および画面キャプチャは旧コンソールをベースに解説しています。新コンソールをご利用の場合は、メニューの配置等が異なりますので、適宜読み替えてご参照ください。
前提
ルールグループとルールについて
URIをマネージドルールの検査から除外する際は、ルールグループ単位で除外するか、ルール単位で除外するかによって実装方法が異なります。
ここでは、コアルールセット (CRS) マネージドルールグループを例に、それぞれの用語を整理します。
| 単語 | 説明 |
|---|---|
| ルールグループ | コアルールセット (CRS) マネージドルールグループ(AWSManagedRulesCommonRuleSet)のように複数のルールを一纏めにしたものです。 |
| ルール | NoUserAgent_HEADERのようにルールグループに含まれる具体的な検査項目です。 |
実装方法
ルールグループから除外する場合
ルールグループ単位で除外する場合は、スコープダウンステートメントを使用します。
スコープダウンステートメントとは、ルールを適用するリクエストの範囲(スコープ)を定義する機能であり、特定の条件に一致するリクエストを検査対象外にできます。
以下に手順を記載します。
1.スコープダウンステートメントを設定する
除外したいWebACLの[Rules]タブから、対象のルールグループを選択します。
[Edit]ボタンをクリックします。
[Scope of inspection]で除外したいURIを指定します。

例:URIが/sampleを除外したい場合
| 項目 | 説明 | 設定例 |
|---|---|---|
| Inspect | 除外する項目を選択します。 (URI、クエリ文字列パラメータ、リクエストヘッダー等が設定できます) |
URI path |
| Match type | 文字列のマッチタイプを選択します。 (完全一致、文字列を含む、文字列から始まる等) |
Exactly matches string(完全一致) |
| String to match | 除外するURIを記入します。 | /sample |
| Text Transformation | 検査前にテキスト変換を行うかを指定します。None(テキスト変換を使用しない)を選択することが多いです。 | None |
設定後、[Save rule] - [Save]で完了です。
ルール単位で除外する場合
ルール単位での除外は、スコープダウンステートメントでは実現できません。そのため、以下の手順で対応します。
- 除外したいルールをCOUNTモードに変更する。
- カスタムルールを作成する。
仕組みを説明しますが、AWS WAFはCOUNTモードのマネージドルールで検知したリクエストに対し、以下規則のラベルをメタデータとして付与します。
awswaf:managed:<提供元>:<ルールグループ名>:<ルール名>
例えばルールグループのAWSManagedRulesCommonRuleSetに含まれるNoUserAgent_HEADERがCOUNTモードで検知すると、以下のラベルが付与されます。
awswaf:managed:aws:core-rule-set:NoUserAgent_Header
このラベルを利用し、「カスタムルールにて上記ラベルが付与され、かつ特定のURIに一致しない場合のみBLOCKする」という条件をカスタムルールで定義することで、仕組みを実装することが可能です。 手順を以下に記載します。
1. 除外したいルールをCOUNTモードに変更する
除外したいWebACLの[Rules]タブより、除外したいルールを含むグループを選択します。
画面右上の[Edit]ボタンをクリックします。
除外したいルールに対し、「Override to Count」を選択します。
設定が完了したら、[Save rule] - [Save]をクリックして設定を完了します。
2.カスタムルールを作成する
除外したいWebACLの[Rules]タブより、[Add rules] - [Add my own rules and rule groups]を選択します。
ルール作成画面が表示されるため、Rule builderを使用してルールを作成します。
URIが/sampleのリクエストを除外したい場合の設定例を以下に記載します。
※ブログの下部にJSONのサンプルも記載しますので、JSONで記述したい場合はご利用ください。
Ruleブロック

| 項目 | 説明 | 設定例 |
|---|---|---|
| Name | ルールの名称を任意で設定します。 | uri-allow-list |
| Type | ルールタイプを選択します。 | Regular rule |
| If a request | ルールの条件を指定します。 | matches all the statements (AND) |
Statement 1ブロック

| 項目 | 説明 | 設定例 |
|---|---|---|
| Negate Statement | StatementをNOT条件にしたい場合に有効化します。 | オフ |
| Inspect | 条件と照合する対象を選択します。 | Has a label |
| Match scope | 条件の一致範囲を指定します。 | Label |
| Match key | 除外したいルールのラベル名を記載します。 | awswaf:managed:aws:core-rule-set:NoUserAgent_Header |
Statement 2ブロック

| 項目 | 説明 | 設定例 |
|---|---|---|
| Negate Statement | StatementをNOT条件にしたい場合に有効化します。 | オン |
| Inspect | 除外する項目を選択します。 (URI、クエリ文字列パラメータ、リクエストヘッダー等が設定できます) |
URI path |
| Match type | 文字列のマッチタイプを選択します。 (完全一致、文字列を含む、文字列から始まる等) |
Exactly matches string(完全一致) |
| String to match | 除外するURIを記入します。 | /sample |
| Text Transformation | 検査前にテキスト変換を行うかを指定します。None(テキスト変換を使用しない)を選択することが多いです。 | None |
Statement 3ブロック
複数のURIを除外したい場合、Statement 2ブロックの設定を参考に、同様の設定を追加します。
Action ブロック

| 項目 | 説明 | 設定例 |
|---|---|---|
| Action | ルールに該当する場合のActionを指定します。 | Block |
最後に[Add rule]をクリックしてカスタムルールの作成を完了します。
なお、今回作成したカスタムルールは、マネージドルールで付与されたラベルを評価する必要があるため、必ずマネージドルールよりPriorityの数値を大きく設定し、後に評価されるように運用してください。
終わりに
ご一読ありがとうございました。
最後にカスタムルールのJSONを記載しますので、JSONからカスタムルールを作成したい場合に修正してご利用ください。
{
"Name": "uri-allow-list",
"Priority": 5,
"Statement": {
"AndStatement": {
"Statements": [
{
"LabelMatchStatement": {
"Scope": "LABEL",
"Key": "awswaf:managed:aws:core-rule-set:NoUserAgent_Header"
}
},
{
"NotStatement": {
"Statement": {
"ByteMatchStatement": {
"SearchString": "/sample",
"FieldToMatch": {
"UriPath": {}
},
"TextTransformations": [
{
"Priority": 0,
"Type": "NONE"
}
],
"PositionalConstraint": "EXACTLY"
}
}
}
}
]
}
},
"Action": {
"Block": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "uri-allow-list"
}
}