WAF
Webアプリケーションを保護するため、アプリケーション層でHTTPの要求などを検査し、攻撃と判断した通信を遮断する機能または装置である。IPアドレスやポート番号だけでは区別しにくいSQLインジェクションやクロスサイトスクリプティングなどへの対策に用いる。
イマシルちゃんの解説
Webサイトへの通信では、正常な検索も攻撃目的の入力も同じ入口へ届くんだ。
接続先やポート番号を許可しただけでは、送られてきた内容まで安全とは判断できないよ。
WAFは、Webアプリケーションを守るためにHTTPの要求を検査する機能や装置なんだ。
アクセス先のURLやフォームの入力などを調べて、攻撃の特徴に合う要求を止めるよ。
例えば、データベースへの命令を入力に紛れ込ませるSQLインジェクションへの対策に使えるの。
普通の利用まで止めないよう、サイトの使い方に合わせて検査ルールを調整することも大切だよ。
この解説はわかりやすかったですか?
より深い解説
Webサイトを公開したまま攻撃を選別する
WAFはWeb Application Firewallの略である。公開Webサイトでは外部からのHTTP・HTTPS接続を受け付ける必要がある。しかし、その入口を開けると正常な利用者だけでなく、アプリケーションの脆弱性を悪用する要求も到達できる。
そこでHTTPの構造や入力値を確認し、通過させる要求を選別する。例えば入力値をSQL命令として解釈させる攻撃や、ブラウザで実行させるスクリプトを紛れ込ませる攻撃の特徴を調べる。検査対象と判定後の処理をルールで定める点は、AWS WAFのルール仕様でも示されている。
ネットワークの接続を制御するファイアウォールと、Webの要求を調べるWAFは役割が異なる。通信の異常や攻撃の兆候を検出するIDS、遮断も行うIPSとも重点が異なる。ただし製品には複数の機能が統合されることがあるため、名称だけで判断せず実際の検査範囲を見る。
| 機能 | 主に確認したいこと | 判断の例 |
|---|---|---|
| ネットワークの通信制御 | 相手・サービス・接続の経過 | 管理用サービスを外部へ公開しない |
| WAF | Webの要求の構造や入力内容 | 検索パラメータに攻撃の特徴が含まれるか調べる |
| IDS・IPS | 対応する通信中の攻撃や不正な振る舞い | 脆弱性を悪用するパターンを検出する |
「443番を許可したからWebは安全」「WAFがあるからすべての通信を守れる」のどちらも適切ではない。利用するサービスと攻撃の種類に合わせて役割を組み合わせる。
要求のどの部分を検査するのか
HTTPの要求には、操作の種類やアクセス先のほか、ヘッダーや本文がある。同じ検索文字列でもURLに含める場合と本文に含める場合があるため、入力がどこへ送られるかを把握しなければ検査の抜けが生じる。
次は正常な問い合わせを例に、検査箇所を整理したものである。
| 箇所 | 例 | 検査の観点 |
|---|---|---|
| HTTPメソッド | GET、POST | その画面やAPIで認める操作か |
| URIのパス | /search、/api/orders | 許可した機能へのアクセスか |
| クエリパラメータ | keyword=network | 入力値の形式や攻撃の特徴を確認する |
| ヘッダー・Cookie | Content-Type など | データ形式や必要な項目が適切か |
| リクエスト本文 | フォーム入力、JSON | 項目ごとの値やサイズを調べる |
URLエンコードされた文字列やJSONを、Webサーバがどのように解釈するかも関わる。単にパケットの中に特定の文字があるか探すだけでは、アプリケーションが実際に受け取る入力と一致しないことがある。対応するデータ形式や正規化の処理を確認する。検査対象の具体例には、本文全体とJSON内の要素を分けて指定する方法もある。
レスポンスの検査や情報漏えい防止に対応する製品もあるが、すべてのWAFが応答本文まで検査するとは限らない。利用する製品で要求・応答のどちらを扱うか確認する必要がある。
攻撃の特徴と正常な入力をルールにする
よく使われる方法は、既知の攻撃の特徴を表すシグネチャに照合する方法と、受け付ける入力をあらかじめ定義する方法である。
前者はさまざまなWebサイトに共通する攻撃へ広く対応しやすい。一方、サイト固有の文脈を完全に把握しているわけではなく、正常な入力が特徴に一致する場合もある。後者の許可リスト方式では、ある項目は数字だけ、あるAPIでは特定のメソッドだけという形で受け付ける範囲を決める。仕様変更に合わせて定義も更新する必要がある。
一つの一致だけで遮断せず、複数のルールに一致した結果を点数として合計する方法もある。OWASP Core Rule Set(CRS)では、この異常スコアが設定したしきい値に達したかを判断に使う。個々のルールに一致することと、最終的に要求を遮断することは同じとは限らない。CRSの判定方式で、この関係が説明されている。
製品が提供するマネージドルールは共通の攻撃への対策を取り込みやすい。組織が作成するカスタムルールは、管理画面や業務APIなど固有の条件を反映できる。共通ルールを有効にするだけで完了とせず、自分のアプリケーションで必要な条件と例外を整理する。
暗号化された通信を検査する場所
HTTPSのHTTPデータはTLSで暗号化される。WAFがその内容を検査するには、復号後のデータを見られる場所に置く必要がある。代表例が、Webサーバの手前で接続を受け付けるリバースプロキシ構成である。
- ブラウザはWAFやその前段の配信サービスへHTTPSで接続する。
- その場所でTLS終端を行い、復号したHTTPの要求を検査する。
- 通過を認めた要求を、実際のコンテンツを提供するサーバへ送る。
- 後半の区間も保護する構成では、新しいTLS接続で再暗号化する。
前半がHTTPSでも、後半まで自動的に暗号化されるわけではない。後半でHTTPSを使う場合は、証明書の有効期限や接続先名の検証も行う。例えばCloudflareのFull(strict)は、両区間を保護し、接続先サーバの証明書も確認する構成である。
WAF機能をWebサーバのモジュールとして動かし、サーバ内で復号された要求を調べる構成もある。「専用の箱を置くこと」だけがWAFの実現方法ではない。設置形態が違っても、検査できるデータと実際に遮断できる場所を明確にすることが必要である。
検査を通らない経路を残さない
クラウド型のWAFを前段に置いた場合、背後でコンテンツを提供する実サーバをオリジンサーバという。DNSの接続先をWAFへ向けても、実サーバの公開IPアドレスへ直接接続できれば、その経路では検査を通らないことがある。
対策としては、実サーバへの接続元を前段のサービスや必要な管理経路へ限定する。構成に応じて相互TLSによる認証や、外部から直接到達できないトンネル接続も利用できる。IPアドレスを非公開にするだけに頼らず、サーバ側で受け入れる通信を制限する。Cloudflareの実サーバ保護の資料は、複数の方法とそれぞれの条件を示している。
プロキシを経由すると、IPヘッダーの送信元が元の利用者から変わる場合がある。利用者単位の判定やログには X-Forwarded-For などを使うことがあるが、利用者が送ったヘッダーを無条件に信用してはならない。信頼する中継装置が値をどう生成・上書きするかを決める。転送されたIPアドレスの扱いも検査ルールの一部になる。
検査できる量と形式には限界がある
製品には本文の検査サイズや、扱えるヘッダー数などの上限がある。巨大なアップロードを受け付けたとき、すべてのバイトを検査できるとは限らない。上限を超えた要求を拒否するのか、検査できた範囲だけで判断するのかも確認する必要がある。
例えばAWS WAFでは検査可能な量が連携するサービスによって異なり、上限を超えた部分が検査されないまま後段へ渡る構成もある。具体的な数値を全製品共通の仕様として覚えるよりも、「検査対象の上限と超過時の処理を合わせて確認する」という判断が重要である。サイズ超過時の公式仕様を参照する。
また、フォームとJSONでは解析方法が異なる。対応する Content-Type と本文の形式が合っているか、APIの更新で入力箇所が変わっていないかを点検する。新しい機能を追加したら、アプリケーションの動作確認とWAFの検査確認を一緒に行う。
正常な利用を止めずに調整する
正常な要求を攻撃と判断することを誤検知という。反対に、攻撃を検出できないことを見逃しという。検査を強めればよいという単純な関係ではなく、利用者が必要な操作を続けられる範囲で攻撃を止める必要がある。
例えば記事投稿画面ではHTMLの入力が正常な用途である場合がある。その文字列が攻撃検知ルールに一致したからといって、サイト全体で同じルールを無効にするのは範囲が広すぎる。対象URLやパラメータを限定して、どの検査を例外とするか検討する。CRSの調整手順でも、必要な範囲へ絞ったルール除外を扱っている。
導入時は、まず試験環境で正常系と攻撃を想定したテストを行う。その後、遮断せず記録するモードで実際の利用への影響を確認し、段階的に遮断を有効にする。これはAWSのテストと調整の手順でも勧められている。
ルールには優先順位と判定後の動作がある。例えばAWS WAFの Count は記録後も後続ルールの評価を続けるが、Allow や Block は評価を終了する。先に広い許可ルールを置くと、後ろの検査まで進まない場合がある。ルールの動作仕様に沿って順番を設計する。
要求数の制御と根本修正を組み合わせる
WAF製品には、一定期間の要求数を条件にするレート制限を備えるものもある。ログイン画面への大量アクセスなどを抑える用途に使える。ただしIPアドレス単位の集計では、企業のNAPTや共有プロキシを利用する複数人が一つの送信元として見える場合がある。集計の単位、対象URL、通常の利用量を考えて条件を決める。AWSのレートベースルールは、集計条件と対象の絞り込みを説明している。
脆弱性を利用する要求をWAFで遮断し、アプリケーションを直すまでの危険を抑える対策は仮想パッチと呼ばれる。ただし、アプリケーションの欠陥そのものが修正されたわけではない。ルールを回避する入力や検査されない経路まで完全に防げるとは限らない。OWASPの脆弱性対策資料も、危険を減らす対策と根本修正を区別している。
SQLインジェクションには、SQL文の構造と値を分けるパラメータ化クエリなどの対策が必要である。XSSには、出力先の文脈に合うエスケープやサニタイズなどを行う。WAFを有効にした後も、SQLインジェクション対策やXSS対策をアプリケーション側へ実装する。
認証済み利用者が他人のデータを取得できる権限管理の不備などは、単純な攻撃パターンだけでは判断しにくい。業務上の権限や処理順の正しさは、アプリケーション側でも検証しなければならない。
検査機能が停止した場合の動作を決める
検査機能の停止や過負荷で要求を検査できない場合に、未検査のまま通信を通す方針をフェイルオープン、通信を止める方針をフェイルクローズという。前者では業務を継続できても攻撃が検査を通らずに届くおそれがあり、後者では正常な利用も停止し得る。選択できる動作は製品と構成によって異なるため、業務の継続要件と保護要件に合わせて決める。
例えばF5 WAF for NGINXの仕様では、検査エンジンの停止・切断・CPUやメモリの過負荷時に、要求を通すか拒否するかを設定できる。処理能力や冗長化もあわせて検討し、複数台で同じサービスを保護する構成では検査ルールや関連設定の一致を確認する。単にWAFを追加するだけで可用性まで保証されるわけではない。
ログと構成から原因を調べる
利用者に403などのエラーが見えても、WAFが原因とは限らない。Webサーバやアプリケーション自身も拒否応答を返せるため、要求の時刻や識別子を使って各装置のログを突き合わせる。次は調査のための独自例である。
| 症状 | 確認すること |
|---|---|
| 一部の入力だけ拒否される | 一致したルール、対象項目、正常な入力の仕様を確認する |
| 新しいAPIだけ期待どおり検査されない | 接続経路、検査対象、本文の形式と解析設定を確認する |
| アップロードだけ失敗する | サイズ制限と超過時の処理を、WAFとアプリケーションの両方で調べる |
| 前段を経由した接続だけ失敗する | 後段への通信許可、TLSの証明書検証、名前解決を確認する |
| ルール変更後も一部で挙動が違う | 適用先と設定の反映状況、先に一致するルールを確認する |
ログに本文やCookieを記録する場合は、認証情報や個人情報を不要に保存しない設定も検討する。調査に必要なルールIDや対象項目を残しながら、記録範囲と閲覧権限を絞る。
設計問題での考え方
「HTTPSを使うWebサイトへWAFを追加する」問題では、まずどこで復号し、どの経路の要求を検査するかを決める。その後、実サーバへの直接接続を制限できるか、後半の通信をどう保護するかを確認する。
「正常な投稿が遮断された」問題では、一致したルールと入力項目をログで特定し、例外の範囲を必要最小限にする。「WAFがあるのになぜプログラムを直すのか」には、通信の選別では脆弱性自体は除去されず、検査を回避する入力や経路の可能性も残るためだと説明できる。