セキュリティ

WAFルールの書き方:マネージドルールの当て方と誤検知の切り分け・カスタムルールの判断

WAFルールの書き方:マネージドルールの当て方と誤検知の切り分け・カスタムルールの判断

WAFルールは「どのリクエストに一致したら」という条件と「止めるか、数えるか」というアクションの組で、上から順に評価されます。本記事では、AWS WAFのマネージドルールの導入手順、ログによる誤検知の切り分け、ラベルで一部のパスだけ除外する書き方をJSONとクエリで示し、OWASP CRSとCloudflareでの同じ作業とカスタムルールを足す判断基準も扱います。WAFの仕組みそのものはWAFとは?仕組み・ファイアウォール/IPS・IDSとの違いと企業の選び方を解説をご覧ください。仕様は2026年10月時点の各公式ドキュメントによります。

まとめ:マネージドルールをCountで入れ、誤検知はラベルとパスで狭く除外する

WAFルールの土台は、ベンダーが保守するマネージドルールです。AWS WAFならCore rule set(700WCU)とKnown bad inputs(200WCU)から始め、最初は個々のルールをCountにしてログで一致の中身を確かめ、問題がなければBlockへ戻します。

誤検知が出たルールは、Countに下げて終わりにしません。Countのままだと、そのルールの保護は全パスで消えます。ルールが付けるラベルと除外したいパスを組み合わせたカスタムルールを後ろに置き、該当パス以外では引き続き止める形にします。

カスタムルールを自分で書くのは、管理画面のIP制限やログインURLのレート制限のように、自社の構成でしか決まらない条件に限ります。攻撃パターンを自作の正規表現で書き足すことは勧めません。

WAFルールの構成要素|条件とアクション・評価順を製品ごとに比べる

製品ごとに用語は違っても、WAFルールの骨組みは共通です。骨組みを押さえておくと、誤検知の切り分けで「どのルールが、どの順番で、何をしたか」をログから読めます。

1本のWAFルールを一致条件とアクションの2つに分けて読む基本構造

AWS WAFのルールは、検査する場所(URIパス、クエリ、ヘッダ、本文など)と一致の方法(文字列一致、正規表現、SQLインジェクション検出など)を書いたStatementと、一致したときのActionでできています。条件はAndStatementやNotStatementで入れ子にでき、「/adminで始まり、かつ社内IPではない」のような組み合わせを1本で表せます。

AWS WAFのルールアクションは、Allow・Block・Count・CAPTCHA・Challengeの5種類です。Blockが既定で返す応答は403です。Countは一致を記録するだけで評価を続ける非終了アクションで、ラベルを付けて後続のルールに判断を渡せます。誤検知の調整はこのCountとラベルを軸に組み立てます。

優先度の小さい順に評価し最初の終了アクションで止まる評価順の仕組み

ルール優先度のページによると、AWS WAFはWeb ACL内のルールを優先度の数値が小さいものから評価し、終了アクション(Allow・Block)に当たった時点で止まります。ルールグループの中身はそのグループの位置でまとめて評価され、どのルールにも一致しなければWeb ACLの既定アクションが適用されます。

この順序から、配置の原則は2つ決まります。誤検知を救うAllowのルールは、救いたいマネージドルールより前に置かないと効きません。ラベルを読むルールは、ラベルを付けるルールより後ろに置かないと何も一致しません。並べ方の誤りは設定エラーにならず、黙って効かない状態になる点に注意が要ります。

AWS WAF・Cloudflare・OWASP CRSのルール構造と外し方の比較

マネージドルールの判定方式と、誤検知したルールの外し方は製品で違います。

観点 AWS WAF Cloudflare WAF OWASP CRS(ModSecurity等)
判定方式 ルールごとに一致したら即アクション 独自ルールとスコア型CRS 一致ごとに点数を加算し合計で判定
カスタムルールの書き方 JSONのStatementを入れ子にする Rules languageの式 SecRuleディレクティブ
誤検知時の外し方 ルール単位でCountに上書き 例外(Skip)を作る ルールIDや変数単位の除外
一部パスだけ外す方法 ラベル一致+除外パスのルール 例外の式にパス条件を書く ctl:ruleRemoveTargetById
容量の上限 Web ACLあたり5,000WCU プランごとのルール本数 サーバーの処理性能次第

AWS WAFは止めたルールが1対1で分かる反面、除外の記述は長くなる傾向です。CRSは合計点で判定するため、1つのルールを外しても他のルールの点で止まることがあり、切り分けが難しくなります。Google CloudのCloud ArmorもCRS由来のルールを持ち、詳細はCloud Armorとは?Google CloudのWAF/DDoS防御の仕組み・料金・実装判断で扱っています。

マネージドルールを当てる手順|Countで入れてBlockへ戻す流れ

中身を把握しないまま全ルールをBlockで入れると、正規の利用者が403を受けたときに原因を追えません。AWS WAFを例に、導入から本番の遮断までの作業を示します。

Core rule setの検査内容とラベル名を導入前に控える作業

ベースラインのルールグループ一覧には、ルールごとの検査内容と付与されるラベルが載っています。Core rule set(AWSManagedRulesCommonRuleSet)は700WCUで、サイズ制限・XSS・ローカルファイルインクルージョン・EC2メタデータへのSSRFなど20本のルールを含みます。

誤検知に直結するのはサイズ制限の4本です。クエリ文字列は2,048バイト、Cookieヘッダは10,240バイト、URIパスは1,024バイト、本文は8KB(8,192バイト)を超えるとBlockします。検索条件を長いクエリで渡す画面や、大きなJSONを受け取るAPIを持つなら、入れる前に該当するルール名を控えておきます。Log4jやSpringのRCEを検出するKnown bad inputs(AWSManagedRulesKnownBadInputsRuleSet)は200WCUで、誤検知は比較的少なめです。

RuleActionOverridesでルールごとにCountへ切り替える書き方

導入時は、ルールグループ内のルールを1本ずつCountに上書きして入れます。次の例は、Core rule setのうちサイズ制限の本文ルールとXSSの本文ルールをCountにし、それ以外は既定どおりBlockで動かす設定です。

{
  "Name": "aws-common",
  "Priority": 10,
  "Statement": {
    "ManagedRuleGroupStatement": {
      "VendorName": "AWS",
      "Name": "AWSManagedRulesCommonRuleSet",
      "RuleActionOverrides": [
        { "Name": "SizeRestrictions_BODY", "ActionToUse": { "Count": {} } },
        { "Name": "CrossSiteScripting_BODY", "ActionToUse": { "Count": {} } }
      ]
    }
  },
  "OverrideAction": { "None": {} },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "aws-common"
  }
}

2022年10月27日より前に作ったWeb ACLには、同じ意味の古いExcludedRulesが残っている場合があります。公式ドキュメントはRuleActionOverridesへの書き換えを推奨しており、古い形式のルールはコンソールのサンプルリクエストにも表示されません。WCUの合計はWCUの説明ページにあるとおりWeb ACLあたり1,500までが基本料金で、上限は5,000です。API GatewayやCognitoへの関連付け手順と料金の積算はAPI GatewayにAWS WAFを関連付ける手順:Web ACLのルール設計・WCU計算とCognito保護にまとめました。

ルールグループ全体のCount上書きをテストに使わない理由と使いどころ

Web ACL側のOverrideActionをCountにすると、ルールグループ全体をまとめてCountにできます。手軽ですが、公式ドキュメントはこれをテストには向かないと明記しています。グループ内の評価は通常どおり進み、最初に一致した終了ルールで評価が止まるため、後ろのルールが一致したかどうかがログに残りません。

テストでは、個々のルールをRuleActionOverridesでCountにするほうが、どのルールが何件一致したかを全部数えられます。グループ全体のCountは、ベンダーが新しい版を出した直後に一時的に影響を止める非常用と考えます。

誤検知の切り分け手順|WAFログの遮断ルールとラベルから原因を特定する

「保存ボタンを押すと403になる」と連絡が来たら、推測でルールを外さず、ログで止めたルールを特定します。

Logs Insightsで遮断したルール名とURIパスを件数順に並べるクエリ

WAFログのフィールド定義では、遮断したWeb ACL上のルールがterminatingRuleId、ルールグループの中で実際に一致したルールがruleGroupListのterminatingRule.ruleIdに入ります。Countで一致したルールはnonTerminatingMatchingRulesに、上書き前のアクションはoverriddenActionに記録されます。

fields @timestamp, httpRequest.uri, terminatingRuleId,
       ruleGroupList.0.terminatingRule.ruleId as innerRule
| filter action = "BLOCK"
| stats count(*) as hits by terminatingRuleId, innerRule, httpRequest.uri
| sort hits desc
| limit 50

CloudWatch Logs Insightsでaws-waf-logs-で始まるロググループに対して実行します。ruleGroupList.0は配列の先頭要素なので、ルールグループを複数入れているなら.1以降も確かめます。特定のURIに件数が偏っていれば誤検知の候補です。S3に出力したログを長期間にわたってAthenaで集計する方法は、WafCharmとは?AWS WAF自動運用の導入手順・WCU消費・料金の実額の誤検知の章で扱っています。

本文サイズの上限とXSS判定で起きやすい業務システムの誤検知の型

業務システムで目立つ誤検知は、ほぼ2つの型に分かれます。1つ目は本文サイズです。画像をBase64で埋めた送信や、明細行の多い注文データは8KBを簡単に超え、SizeRestrictions_BODYで止まります。2つ目は入力欄の中身です。CMSの本文欄、問い合わせフォームの自由記述、マークダウンエディタはHTMLタグや記号を含むため、CrossSiteScripting_BODYやSQLインジェクション系のルールが反応します。

ログのhttpRequest.uriが1〜2個のパスに集中しているなら、そのパスだけを除外の対象にします。多くのパスに散っているなら、ルールの検査内容と自社の入力仕様が合っていないので、ルールをCountのまま運用し、アプリケーション側の入力検証で補います。

Countに下げたルールをラベルと除外パスの組み合わせで再びBlockする

Countにしたルールも、一致すればラベルを付ける仕組みです。ラベル一致ステートメントは1WCUで、先に評価されたルールが付けたラベルだけを読めます。これを使い、「本文サイズのラベルが付いていて、かつアップロード用のパスではない」リクエストを後ろのルールで止めます。

{
  "Name": "block-large-body-except-upload",
  "Priority": 20,
  "Statement": {
    "AndStatement": {
      "Statements": [
        { "LabelMatchStatement": {
            "Scope": "LABEL",
            "Key": "awswaf:managed:aws:core-rule-set:SizeRestrictions_Body" } },
        { "NotStatement": { "Statement": {
            "ByteMatchStatement": {
              "SearchString": "/api/uploads/",
              "FieldToMatch": { "UriPath": {} },
              "TextTransformations": [ { "Priority": 0, "Type": "NONE" } ],
              "PositionalConstraint": "STARTS_WITH" } } } }
      ]
    }
  },
  "Action": { "Block": {} },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "block-large-body-except-upload"
  }
}

優先度は、Core rule setの10より大きい20にしています。逆にすると、ラベルがまだ付いていない段階で評価されて何も止まりません。ラベルの綴りはルール名と大文字小文字が異なり、ルール名SizeRestrictions_BODYに対してラベルは末尾がSizeRestrictions_Bodyです。ラベル一致の例のとおりキーは完全一致なので、ベースラインのルールグループ一覧からラベル名をそのまま写します。Web ACLに入れる前にaws wafv2 check-capacityへルールのJSONを渡せば、WCUの増分を確かめられます。

OWASP CRSとCloudflareでの誤検知対応|異常スコアの調整とSkipの例外

NginxやApacheにModSecurityやCorazaを載せるならOWASP CRS、CDNの前段で守るならCloudflareのマネージドルールが候補です。誤検知を狭く外す流れはAWS WAFと同じで、外し方の単位が違います。

OWASP CRSの異常スコア5でのブロックとパラノイアレベル1〜4の上げ方

CRSの異常スコアの説明によると、CRSは一致したルールの重大度に応じてCRITICAL=5、ERROR=4、WARNING=3、NOTICE=2の点を加え、合計がしきい値以上なら遮断します。既定のしきい値はリクエストが5、レスポンスが4です。CRITICALのルールが1本当たるだけで止まる設定です。

検知の厳しさはパラノイアレベルの4段階で切り替え、上げるほどルールが増え、誤検知も増えます。公式の手順は、まず実行用のレベルだけを上げて追加ルールの一致をログで観察し、除外を整えてから遮断用のレベルを合わせる進め方です。一般的な業務システムならレベル1で始め、決済や個人情報を扱う画面の要件が出てから2を検討すれば足ります。

SecRuleUpdateTargetByIdで特定のパラメータだけ検査から外す除外

CRSの誤検知と調整のページは、ルールファイルを直接編集せず、ルール除外で対応するよう求めています。ルール全体を外すSecRuleRemoveByIdより、特定の変数だけを外す書き方を優先します。

# 設定時の除外(CRSのinclude行より後に置く)
# 941320(XSS: HTML Tag Handler)の検査対象から本文欄 ARGS:body だけを外す
SecRuleUpdateTargetById 941320 "!ARGS:body"

# 実行時の除外(CRSのinclude行より前に置く)
# /api/posts で始まるリクエストに限り、942100(SQLi検出)から ARGS:query を外す
SecRule REQUEST_URI "@beginsWith /api/posts" \
    "id:1001,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ctl:ruleRemoveTargetById=942100;ARGS:query"

置き場所を間違えると除外が効きません。公式ドキュメントも、設定時の除外はCRSを読み込んだ後、実行時の除外は読み込む前に置くよう注意しています。実行時の除外はパスで条件を絞れるため、AWS WAFのラベル一致+除外パスと同じ狭さで外せます。

Cloudflareのカスタムルール式とマネージドルール例外をプランの上限内で組む

Cloudflareのマネージドルールは、全プランで使えるFree Managed Rulesetと、Pro以上で使えるCloudflare Managed Ruleset・OWASP Core Rulesetに分かれます。OWASP Core Rulesetは一致ごとにスコアを積み、しきい値を超えたら止めるCRSと同じ方式です。

Cloudflareのカスタムルールは、Rules languageの式とアクションの組で書きます。ゾーンあたりのルール本数はFreeが5、Proが20、Businessが100、Enterpriseが1,000で、正規表現を使えるのはBusiness以上です。

(starts_with(http.request.uri.path, "/admin") and not ip.src in {203.0.113.0/24})

上の式にBlockを付けると、社内のIP帯以外から管理画面への到達を止められます。マネージドルールの誤検知は、カスタムルールではなく例外(exception)で外します。例外はマネージドルールセット全体、特定のルールセット、特定のルールのいずれかを、式に一致したリクエストだけスキップさせる仕組みです。Freeプランの5本はIP制限と国制限で埋まりやすいので、例外とカスタムルールの本数を最初に見積もります。

カスタムルールを足すかどうかの判断基準|書く場面と書かずに済ませる場面

カスタムルールは本数が増えるほど評価順の管理と誤検知の調査が重くなります。書くかどうかは、条件が自社の構成でしか決まらないかで決めます。

管理画面のIP制限とログインURLのレート制限をカスタムルールで書く場面

カスタムルールで書くべきなのは、ベンダーが知り得ない条件です。管理画面のパスと社内のIP帯、ログインやパスワード再設定のURL、APIの利用者ごとの想定件数がこれに当たります。AWS WAFのレートベースルールは、評価ウィンドウを60・120・300・600秒から選び、上限は最小10件から設定でき、スコープダウン文で対象のパスを絞れます。

ログインURLだけに「同じIPから5分間に20件」のような低い上限を掛ける設定は、マネージドルールでは表現できません。こうした条件は数本で済み、評価順の管理も難しくないため、カスタムルールで書く価値があります。上限値はまずCountで入れ、ピーク時の正規の件数を測ってから決めます。

攻撃パターンを自作の正規表現で書き足すのを見送る場面とその理由

見送るべきなのは、SQLインジェクションやXSSの検出を自前の正規表現で足すことです。攻撃側はエンコードや大文字小文字の変化で文字列一致を簡単に回避しますし、正規表現は正規の入力にも当たります。マネージドルールはベンダーが新しい攻撃に合わせて更新を続けていますが、自作のルールは書いた担当者が異動すれば誰も直せません。

マネージドルールで止まらない攻撃があるなら、WAFではなくアプリケーション側の問題として扱います。プレースホルダによるSQLの組み立てや、出力時のエスケープで塞ぐほうが確実です。新しい脆弱性への緊急対応として一時的にルールを書く場合も、ベンダーのルール更新が出た時点で削除する期限を決めておきます。

WCUの消費と運用工数から決めるルール本数の上限と外部へ任せる判断

AWS WAFでは、Core rule set・Known bad inputs・SQLデータベース(200WCU)にIPレピュテーションを足すと1,100WCU前後になり、カスタムルールに残る余裕は400WCU程度です。この枠に収まらないほどカスタムルールが増えたら、ルールの統合か、構成の見直しを考える段階です。

版の更新も運用で扱う作業の一つです。版の管理のページのとおり、既定版に任せるか静的な版に固定するかを選べ、IPレピュテーション以外のAWSマネージドルールでは、新しい版の通知先はSNSです。固定した版には期限があるので、通知を受けて検証する担当者がいないなら既定版のまま誤検知の監視を厚くします。監視と調整を社内で回せない場合は、WafCharmのような運用サービスに任せる選択肢もあります。WAFは認可の抜けや業務ロジックの欠陥を止められません。WAFで塞げない箇所を含めたWebアプリケーションの点検は脆弱性診断・セキュリティ診断でご相談いただけます。

よくある質問

WAFルールの設計と誤検知の対応で出やすい疑問に、各製品の公式ドキュメントの記載をもとに答えます。

WAFルールはどの順番で並べればよいですか?

AWS WAFでは、通してよい通信のAllow(監視サービスのIPなど)、明らかに不要な通信のBlock(IP制限・国制限・レート制限)、マネージドルール、ラベルを読むカスタムルールの順が基本です。優先度の小さい順に評価され、終了アクションで止まるため、救済のAllowは前に、ラベルを読むルールは後ろに置きます。

Countにしたルールの一致はログで確認できますか?

ログでの確認は可能です。Countで一致したルールはWAFログのnonTerminatingMatchingRulesに記録され、ルールグループ内で上書きしたルールは元のアクションがoverriddenActionに残ります。付与されたラベルもlabelsに記録され、記録対象は先頭100件までです。Countにしてから数日分のログを集計し、正規の利用で一致した件数がゼロか、特定のパスに限られるかを見てからBlockへ戻します。

マネージドルールの更新で急に誤検知が出たらどうしますか?

AWSマネージドルールは版を固定できるので、前の静的な版が期限内なら一時的に戻して影響を止め、その間に新しい版をCountで検証する方法があります。原因ルールが分かっていれば、そのルールだけをCountにするほうが保護の穴は小さく済みます。

WAFルールでSQLインジェクションは完全に防げますか?

防げません。マネージドルールは既知の攻撃パターンに一致する入力を止めますが、エンコードや構文の変化で回避される余地は残るため、完全な防御ではありません。WAFは被害を減らす前段の防御と位置づけ、アプリケーション側ではプレースホルダでSQLを組み立てます。攻撃の型とコードでの対策はSQLインジェクションの攻撃例と対策を解説した記事で確認できます。

レートベースルールと通常のカスタムルールは何が違いますか?

通常のカスタムルールは1件ずつのリクエストの中身で判定し、レートベースルールは一定時間内の件数で判定します。AWS WAFのレートベースルールは、送信元IPや指定したヘッダなどを単位に件数を数え、上限を超えた間だけアクションを適用します。アクションにAllowは選べません。総当たりログインや、1つのIPからの過剰なAPI呼び出しを止める用途に向きます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.27 テックブログ Brotli 脆弱性:CVE-2026-111497の影響確認とNode.js・Python・.NETの更新手順
  2. 2026.10.28 テックブログ リンツ不正アクセス:314万件の対象確認とパスワード強制リセット後の対処
  3. 2026.10.27 テックブログ Joshin(ジョーシン)不正アクセス:最大600万件の対象とサブスク初期パスワードの対処
  4. 2026.10.28 テックブログ 楽天トラベル不正アクセス:最大約260万件の対象確認とカード下4桁の詐欺対策
  5. 2026.10.23 テックブログ Renta!はいつ再開?不正アクセスでメールアドレス等が流出したおそれ・再開時のパスワード再設定と運営側の対応

RELATED POSTS 関連記事

目次