サーバーの管理画面を眺めていると「WAF設定」という項目、ありますよね。なんとなく良さそうだけど、ONにしたら記事が保存できなくなった……なんて話もちらほら聞くので、触るのをためらっている方も多いのではないでしょうか。今回は「WAFって結局設定すべきなの?」という疑問に対して、WAFの仕組みからメリット・デメリット、サイト規模別の導入パターン、そして誤検知が起きたときの対処法までをまとめてみました。
結論:WAFは基本的に設定すべき。ただし「入れたら安心」ではない
先に結論から言ってしまうと、WordPressなどのCMSやお問い合わせフォーム、ログイン画面があるサイトなら、利用中のサーバーやCDNが提供しているWAFは基本的に活用すべきだと考えています。追加費用なしで使えるものも多いですしね。ただし、ONにして終わりではなく、サイトとの相性や誤検知が起きていないかを確認しながら運用する、というのがセットです。
ただし、ここで勘違いしやすいのが「WAFを入れたからもう安全」という考え方です。WAFはあくまで攻撃っぽいリクエストを手前で弾いてくれる“門番”であって、アプリケーション自体の脆弱性を直してくれるわけではありません。後ほど詳しく書きますが、WAFは保険的な対策という位置づけで考えておくのが正解です。
そもそもWAFとは?普通のファイアウォールとの違い
WAFは「Web Application Firewall」の略で、その名の通りWebアプリケーションを守るためのファイアウォールです。OWASPの解説によると、WAFはHTTPのやり取りに対してルールを適用し、主にクロスサイトスクリプティング(XSS)やSQLインジェクションといった代表的な攻撃をカバーするもの、とされています。
一般的なファイアウォールとの違いは「どこを見ているか」です。従来型のネットワークファイアウォールは、主にIPアドレスやポート番号といった情報で通信を許可・拒否します。(最近はアプリケーション層まで検査できる製品もあるので、あくまで一般的な比較です)一方でWAFは、URLのパラメータやPOSTされたフォームの中身など、HTTPリクエストの“中身”まで踏み込んでチェックします。つまり、443番ポートを通る正規の通信に紛れ込んだ攻撃を見つけるのがWAFの役割、というわけですね。
WAFが防いでくれる主な攻撃
WAFが得意とするのは、パターンがある程度決まっている攻撃です。代表的なのはSQLインジェクション、クロスサイトスクリプティング、ディレクトリトラバーサル、OSコマンドインジェクションあたり。フォームに「<script>」が入っていたり、パラメータに「’ OR 1=1」のような怪しい文字列が含まれていたりすると、WAFがそれを攻撃の兆候として検知します。ただし、文字列が含まれていれば必ずブロックされるわけではなく、どのルールが有効か、ブロックするのか記録だけするのかといった設定次第で結果は変わります。
また、Log4jやShellshockのように、世の中に広く影響する脆弱性が見つかったときにも力を発揮します。アプリ側のアップデートが間に合わない間でも、該当する攻撃パターンのルールが有効になっていれば、攻撃を手前で止められる可能性がある。もちろん脆弱性への対応がそれで完了するわけではありませんが、この「時間稼ぎ」ができるのは地味にすごく大きなメリットなんです。
WAFの導入形態は大きく3タイプ
WAFには導入形態によっていくつかの種類があります。ざっくり分けると、Webサーバーにソフトウェアとして組み込む「ホスト型」、サーバーの手前に専用機器を置く「アプライアンス型(ネットワーク型)」、そしてDNSを切り替えてクラウドのプロキシ経由で通信を検査する「クラウド型」の3つです。IPAも、WAFの製品・サービスは大きく3種類に分けられると整理しています。とはいえ製品ごとに提供形態はさまざまなので、きれいに3つに分かれないものもある、くらいの理解でOKです。
個人ブログや小規模サイトでよく目にするのは、レンタルサーバーに標準搭載されているホスト型と、CloudflareのようなCDNに付いてくるクラウド型でしょう。アプライアンス型は高価で運用体制も必要になるので、基本的には大企業や大規模サービス向けと考えてOKです。(個人で専用機器を買う人はまずいないと思います……)
WAFを設定すべきサイト・優先度が低いサイト
「基本的には設定すべき」とは言ったものの、サイトの性質によって重要度はかなり変わります。ここでは、どんなサイトならWAFの優先度が高いのか、逆にそこまで神経質にならなくていいのはどんなサイトなのかを整理してみます。
設定すべき:WordPress・EC・フォームやログインがあるサイト
真っ先に設定すべきなのは、WordPressをはじめとしたCMSで運用しているサイトです。WordPressは利用者が多いぶん攻撃者にも狙われやすく、プラグインの脆弱性を突く自動化された攻撃が日々飛んできます。プラグインを全部常に最新にしておけるなら理想ですが、現実にはそうもいかないですよね。そのスキマを埋めてくれるのがWAFです。
そしてECサイト。個人情報や決済情報を扱う以上、被害が出たときのダメージが段違いです。EC業界ではカード情報の漏えい事件が定期的にニュースになりますが、一度でも起きれば信用の回復は本当に大変。会員ログイン、カート、問い合わせフォームなど、ユーザーの入力を受け付ける箇所が多いサイトほどWAFの価値は高くなります。
優先度が低い:完全な静的サイト
逆に、HTMLとCSS、JavaScriptだけで構成された完全な静的サイトの場合、WAFの優先度は比較的低めです。サーバー側でユーザー入力を処理する仕組みがなければ、SQLインジェクションのような攻撃はそもそも成立しにくいからです。JamstackでビルドしたLPやポートフォリオサイトなどがこれに当たります。
とはいえ「不要」とまでは言い切れません。JavaScriptの書き方次第では静的サイトでもXSSは起こり得ますし、配信設定のミスといった別の問題もあります。外部のフォームサービスを埋め込んだり、あとからAPIを追加したりと、構成は案外変わっていくものです。CDN側で無料のWAFが使えるなら、ONにしておいて損はないでしょう。優先度が低いというのは「後回しにしてもいい」くらいの意味で捉えてください。
WAFを入れる前に知っておきたいデメリット
ここまで良いことばかり書いてきましたが、WAFにもデメリットはあります。むしろここを知らずにONにすると「なんかサイトが壊れた」と焦ることになるので、導入前に押さえておきたいポイントです。
誤検知で正常なリクエストまで403になる
WAF最大の悩みどころが誤検知です。WAFは「攻撃っぽい文字列」をパターンで判断しているので、正当な操作でも引っかかることがあります。たとえばWordPressの管理画面で、JavaScriptやHTMLのコードを含む記事を保存しようとしたら403 Forbiddenになった、というのは典型的なパターンです。技術ブログでコードを掲載していると、まさにこれに当たりやすいんですよね。
ほかにも、Google Analyticsのタグを貼り付けた設定画面の保存がブロックされたり、テーマエディタの更新が弾かれたりと、管理画面まわりで起きがちです。公開側は問題なく表示されているのに管理画面だけ動かない、という症状なので、WAFが原因だと気づきにくいのもやっかいなところ。「403が出たらまずWAFを疑う」と覚えておくと、切り分けが一気に楽になります。
コストと運用の手間
もう1つは、規模が大きくなるほど増えるコストと運用負荷です。たとえばAWS WAFの場合、作成するWeb ACLの数、ルールの数、受信するリクエスト数に応じて課金される従量課金モデルになっています。初期費用はかかりませんが、アクセスが増えればリクエスト分の料金も増えますし、Bot対策などの追加機能やログ保存にも別途費用がかかります。月額がいくらになるかは、構成ごとに公式の料金ページで試算しておくのが安心です。
また、OWASPの解説でも触れられているように、WAFをアプリケーションに合わせてカスタマイズするには相応の労力がかかり、アプリ側が変わるたびにメンテナンスも必要になります。ルールを入れっぱなしで放置すると、誤検知が増えたり、逆に新しい攻撃をすり抜けられたりします。入れて終わりではなく、定期的にログを見るくらいの運用は覚悟しておきましょう。
WAFはあくまで「保険的対策」。根本はアプリ側で直す
IPAが公開している「安全なウェブサイトの作り方」では、脆弱性への対策を、原因そのものをなくす「根本的解決」と、攻撃による影響を低減する「保険的対策」に分けて整理しています。WAFはまさに後者の保険的対策にあたります。SQLインジェクションを防ぐ本命は、あくまでプレースホルダを使ったSQLの組み立てなんですよね。
フロントエンドの感覚で言うと、「多層防御の一枚」という点ではフロントとサーバーの二重バリデーションに近い考え方です。仕組み自体はまったく別物ですが、フロントのチェックだけを信じてサーバー側を省略しないのと同じで、「WAFがあるからアプリ側のエスケープ処理は雑でいいや」は絶対にNG。二重三重に守るための一枚として考えるのが健全です。
ちなみに、2011年に報じられたIPAの調査では、WAFを導入済みと回答した企業は全体の25.8%にとどまっていたそうです。あくまで当時の数字で、現在の導入率を示すものではない点に注意してください。導入が進まない背景には、費用や工数が見えにくく、ほかの対策と費用対効果を比べにくいという事情があったとのこと。今はクラウド型や無料プランなど選択肢が広がり、導入のハードルは当時より下がっています。
サイト規模別・WAFのおすすめ導入パターン
では実際に、どんな形でWAFを導入するのが良いのでしょうか。ここではサイトの規模や運用体制ごとに、現実的な導入パターンを3つに分けて紹介します。自分のサイトに近いものを参考にしてみてください。
個人ブログ・小規模WordPress:レンタルサーバーのWAF+CDNの無料プラン
個人ブログや小規模なコーポレートサイトなら、まずはレンタルサーバーに標準で付いているWAF機能をONにするところから始めましょう。多くの国内レンタルサーバーでは、管理画面からワンクリックで有効化できるようになっています。追加費用がかからないケースがほとんどなので、真っ先にやっておきたい対策です。
さらに一歩進めるなら、Cloudflareの無料プランもおすすめです。Cloudflareは2022年に、WAFのマネージドルールセット「Free Managed Ruleset」を全プランに無料で提供すると発表しました。Log4jやShellshock、よくあるWordPressの脆弱性を狙った攻撃に対するルールが含まれていて、無料プランでも利用できます。
ただし「WAFの全機能が無料」というわけではなく、Cloudflare Managed RulesetやOWASP Core Rulesetなどは有料のProプラン以上が対象です。プランごとの機能は変わることがあるので、導入前に公式ドキュメントで確認しておきましょう。
Cloudflareを使うときにもう1つ注意したいのが、DNSレコードのプロキシ設定です。CloudflareのWAFが効くのは、対象レコードでプロキシ(オレンジの雲マーク)が有効になっている通信だけ。さらにオリジンサーバーのIPアドレスに直接アクセスできる状態だと、Cloudflareを経由せずにWAFをすり抜けられてしまう場合があります。オリジン側でCloudflare以外からのアクセスを制限しておくと安心です。
ECサイト・中規模以上:クラウドWAFで本格運用
ECサイトや会員制サービスなど、扱うデータの重要度が高いサイトでは、AWS WAFのようなクラウドWAFや、ベンダーがルール管理まで面倒を見てくれるSaaS型WAFを検討するのが現実的です。AWS WAFならCloudFrontやALBと組み合わせて導入でき、マネージドルールをベースに自社サービスに合わせたカスタムルールも追加できます。
この規模になると、IPごとのリクエスト数を制限するレートベースのルールも活用したいところです。AWS WAFでは、設定した評価時間(1・2・5・10分から選択、既定は5分)内のリクエスト数がしきい値を超えたIPアドレスに対して、レート制限をかけられます。ログイン画面への総当たり攻撃や、カート周りへの大量アクセス対策として有効です。どのルールが何をブロックしたのか、ログを確認できる体制もセットで整えておきましょう。
自前で運用したい:ModSecurity・Coraza+OWASP CRS
VPSなどで自分でサーバーを管理していて、WAFも自前で運用したいという場合は、オープンソースのWAFという選択肢があります。OWASPのWAFプロジェクトには、2002年から使われているModSecurityと、Go言語で作られた比較的新しいCorazaという2つのWAFエンジンがあり、どちらも無料で利用できます。
エンジンはあくまで「検査する仕組み」で、何を攻撃とみなすかは別途ルールセットで決めます。そこで両エンジンに対応しているのが「OWASP Core Rule Set(CRS)」というルールセットで、OWASP Top 10に挙げられる脆弱性をはじめ、幅広い攻撃パターンを検知するルールが揃っています。ただし、自前運用は誤検知のチューニングもすべて自分の責任になるので、ログを読む時間を確保できる方向けです。ぶっちゃけ、時間がないならクラウド型に任せたほうが幸せになれると思います。
WAFで誤検知が起きたときの対処手順
最後に、WAFをONにしたら403エラーが出るようになった、というときの対処法です。焦ってWAFを丸ごとOFFにしたくなりますが、本番環境でそれをやると、その間は攻撃も素通りになってしまいます。基本の流れは「ログで切り分ける→原因のルールを特定する→必要最小限だけ除外する→再テストする」です。
ログで403の原因を切り分ける
まずは403が出た時刻、URL、操作内容をメモして、WAFのログやセキュリティイベントを確認します。WAFのログが見られないサービスなら、サーバーやアプリケーションのエラーログもチェックしましょう。403の原因はWAFとは限らず、パーミッションや.htaccessのアクセス制御が原因のこともあるので、まずはログで当たりをつけるのが先です。
WAFが原因だとわかったら、ブロックされたリクエストと一致したルールIDや検知内容を探します。多くのWAFでは、ログにブロックの理由やルールIDが記録されているはずです。可能であれば、ブロックせずに記録だけする検知モードや、テスト環境で同じ操作を再現して、本当にそのルールの誤検知なのかを確かめておくと確実です。
除外は必要最小限にして、最後に再テスト
ルールが特定できたら、そのルールだけ、あるいは特定のパラメータだけを除外する設定を入れます。管理画面配下のURLをまるごと検査対象から外す方法は手軽ですが、守りが一気に弱くなるので慎重に判断してください。レンタルサーバーによっては「SQL対策」「XSS対策」のようにカテゴリ単位でON・OFFを切り替える方式もあり、その場合も対象はできるだけ絞りましょう。
どうしても本番でWAFを無効化して確認する必要がある場合は、対象と時間を限定し、検証が済んだらすぐに元の設定へ戻します。最後に記事の保存やフォーム送信、ログインなどを再テストして、正常に動くことと、意図しない除外が残っていないことを確認すれば完了です。ちゃんと元に戻す、これだけは絶対に忘れないでくださいね。
まとめ
WAFは設定すべきかどうか、という問いに対しては「WordPressやEC、フォームのあるサイトなら基本はON」というのが今回の結論です。特にレンタルサーバー標準のWAFや、Cloudflareの無料プランのように追加コストなしで使えるものは、まず活用を検討したいところ。ただし、防げる攻撃や誤検知の起きやすさは製品やルールによって違うので、導入後に正常な操作が妨げられていないかの確認はセットで行いましょう。
一方で、WAFはあくまで保険的対策です。SQLインジェクションならプレースホルダ、XSSならエスケープ処理といった根本的な対策をアプリ側でしっかりやったうえで、その外側にWAFを置く。この順番を間違えなければ、WAFは心強い味方になってくれます。「WAFがあるから大丈夫」ではなく、「WAFもあるからより安心」くらいの距離感がちょうどいいのではないでしょうか。
そして導入後に避けて通れないのが誤検知です。管理画面で記事が保存できない、設定が反映されないといった403エラーが出たら、まずWAFを疑ってみてください。本番でWAFを丸ごとOFFにするのではなく、ログからルールを特定して必要最小限だけ除外する。この手順を知っておくだけで、WAFとの付き合い方はかなり楽になるはずです。
まだサーバーの管理画面でWAFがOFFになっている方は、この機会にぜひ一度ONにしてみてください。思わぬところで、見えない攻撃からサイトを守ってくれているかもしれません。
【参考文献】
OWASP「Web Application Firewall」
https://owasp.org/www-community/Web_Application_Firewall
OWASP WAF Projects(ModSecurity / Coraza / CRS)
https://waf.owasp.org/
IPA「Web Application Firewall 読本」改訂第2版(2011年)および補足資料「Web Application Firewallの導入に向けた検討項目」(2019年)掲載ページ
https://www.ipa.go.jp/archive/security/vuln/waf.html
IPA「安全なウェブサイトの作り方」
https://www.ipa.go.jp/files/000017316.pdf
クラウド Watch「IPA、『Web Application Firewall(WAF)読本 改訂第2版』を公開」
https://cloud.watch.impress.co.jp/docs/news/430134.html
The Cloudflare Blog「WAF for everyone: protecting the web from high severity vulnerabilities」
https://blog.cloudflare.com/waf-for-everyone/
Cloudflare Docs「Managed Rules」
https://developers.cloudflare.com/waf/managed-rules/
AWS「AWS WAF の料金」
https://aws.amazon.com/jp/waf/pricing/
AWS Documentation「Rate-based rule high-level settings」
https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based-high-level-settings.html