- ブラウザURL入力
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口今ここ
- アプリ処理
- DB保存
第36週のレート制限は「量」で止める仕組みでした。WAFは「中身」で止めます。同じ段に置かれますが、見ているものが違います。
まず結論
WAFのルールは一致してもその場で遮断せず、スコアに加算するだけです。判定は全ルールの実行後にまとめて行われます。
ただし「少しずつ溜まって閾値を超える」は誤りです。閾値5・CRITICAL 5・比較は `@ge`(以上)なので、既定ではCRITICAL 1本で遮断に至ります。
CRS(OWASP Core Rule Set)を既定設定で使っているとき、SQLインジェクション検出のルールが1本だけ一致しました。このリクエストはどうなるでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
検出する係と、遮断する係を分ける
WAFはHTTPの中身を見て攻撃を止める仕組みです。第36週のレート制限が「量」で止めたのに対し、こちらは「中身」で止めます。
素朴に考えると、WAFは「怪しいパターンに当たったら、その場で遮断する」ように思えます。CRS の既定方式はそうではありません。個々のルールは検出だけを担当し、遮断の判断はしません。 公式はこの設計を一文で言い切っています。「the inspection/detection rule logic is decoupled from the blocking functionality」(検出のルールと遮断の機能が切り離されている)。
ルールが一致すると、遮断ではなくスコアへの加算が起きます。全ルールを実行し終えてから、合計と閾値を比べて初めて遮断が決まります。単独では決め手に欠ける弱い手がかりでも、いくつも重なれば判断できるからです。
ルール942100 を3段階で追う
CRS v4.29.0 のルール 942100(SQLインジェクションの検出)で、仕組みの経路だけを見ます。
段階 ルール やること加算 942100 severity CRITICAL → PL1のスコアに +5合算 949060 PL1のスコアを合計値に足す(フェーズ2)比較 949110 合計 @ge 閾値(既定5) なら deny
942100 自身は setvar で加算するだけで deny を持ちません。遮断は949110 の仕事です。
このルールが見ているのは、クッキーの値と名前、User-Agent、Referer、パラメータの名前と値、XMLのノードと属性。「URLを見ている」では収まりません。 判定は正規表現ではなく libinjection というライブラリが行い、URLデコード等を施してから調べます。
「WAFはURLを見て怪しいパターンを弾いている」という説明は、CRSの検査対象と合っていますか。
ここが本題 — 「少しずつ溜まる」は既定では起きない
ここまでを読むと、こう考えたくなります。「弱い手がかりが少しずつ加算され、積み上がって閾値を超えたところで遮断される」。筋は通っていますが、既定の挙動としては誤りです。
数字を並べれば分かります。閾値は5。CRITICALの加算値も5。そして比較は @ge、つまり「以上」です。
インバウンド閾値 5 (ルール901100)CRITICAL の加算値 5 (ルール901140)比較演算子 @ge (ルール949110)→ 5 >= 5 なので、CRITICAL 1本で到達する
crs-setup.conf.example 自身が明記しています。「a single critical rule match will cause the request to be blocked and logged」(CRITICALのルール1本の一致で、リクエストはブロックされログに記録される)。
CRSの既定で、WARNING(加算値3)のルールが1本だけ一致した場合はどうなりますか。
WAFのアノマリスコア
一致したルールはその場で遮断せず、スコアに加算します。全ルールの実行後に合計値を閾値と比べて遮断を決めます。個々の一致は結論ではなく、最後の比較に持ち込む材料です。
一致したルール 加算 合計NOTICE 相当 +2 2WARNING 相当 +3 5判定: 5 >= 5 → 遮断
ルーティング表の最長一致(第18週)
第18週で見たとおり、宛先に当てはまる行は普通は複数あります。ルータはそれを足し合わせず、最も細かく指定している1行だけを選びます。当てはまった行の数は効きません。
当てはまる行 一致ビット数0.0.0.0/0 0192.168.1.0/24 24192.168.1.128/25 25 ← これが選ばれる
「複数当てはまる」ところまでは同じなのに、ルーティング表とWAFでは結論の出し方が正反対です。2つに共通する構造は何で、なぜ決め方が逆向きになるのでしょうか。
「当てはまった候補をどう扱うか」と「それぞれが何を答えようとしているか」の両方を比べてください。
この章のまとめ
- CRSのルールは一致しても遮断しない。検出と遮断が切り離され、加算だけを行う。
- 経路は3段階。942100 が加算 → 949060 が合算(PL2〜4 は 949061〜949063) → 949110 が比較して
deny。 - 既定は閾値5 / CRITICAL 5 / 比較は
@ge(以上)。CRITICAL 1本で遮断に至る。加算が効くのはWARNING(3)やNOTICE(2)が重なる場合。 - 検査対象はURLだけではない。パラメータやクッキーの名前と値、ヘッダ、ボディ、レスポンスまで見ている。
- 「2フェーズ」は用語のずれ。検査は5フェーズ、ブロック判定は2回(早期ブロック有効時は4回)。
- パラノイアレベルは公式の説明では1〜4、既定1(0も設定値としては受け付ける)。閾値とは別物。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
CRSのアノマリスコア判定として、最も正確なのはどれですか。
用語集(6語)
- WAF (Web Application Firewall)
- HTTPの中身を検査して攻撃とみなした通信を遮断する仕組み。レート制限が「量」で止めるのに対し「中身」で止める。脆弱性を直すものではなく緩和する仕組みである点に注意。
- OWASP Core Rule Set (CRS)
- WAFエンジン上で動く汎用の検出ルール集。本レッスンの数値は v4.29.0 の実ファイルで確認した。特定のアプリを知らずに検出するため、誤検知が構造的に避けられない(第38週)。
- アノマリスコア (anomaly score)
- 1件のトランザクションがどれだけ異常に見えるかを表す累計値。個々のルールは加算するだけで遮断しない。公式は collaborative detection と delayed blocking の組み合わせと説明している。
- アノマリスコア閾値
- 遮断の判定に使う基準値。v4.29.0 の既定はリクエスト側5、レスポンス側4。比較は `@ge`(以上)。CRITICALの加算値も5なので、既定ではCRITICAL 1本で到達する。
- 重大度と加算値
- CRITICAL=5 / ERROR=4 / WARNING=3 / NOTICE=2。ルール901140〜901143 が設定する。加算が実際に効くのはWARNINGやNOTICEが複数重なる場合。
- パラノイアレベル
- どれだけ積極的に検出するかの段階。公式が説明するのは1〜4で既定は1(0も設定値としては受け付け、PL1以上のルールを飛ばす)。上げると有効なルールが増え、同時に誤検知も増える。閾値とは別物で、公式は「直接の関係が無い2つ」と明示している。