全3回この記事は、シリーズの第1回(入門編)です。第2回・第3回の実践編へと続きます。

WAF について、筆者はずっとこんな認識でいました。

なんとなく、情報漏洩のようなセキュリティの問題から何かしら守ってくれるもの。その一方で、サイトを作っていると謎のエラーを引き起こす厄介者。

守ってくれるのはありがたい。でも、WordPressでサイト作成をしていると、こんな形で作業を止めてくるのも、だいたい WAF が絡んでいます。

ウィジェットが保存できない
プラグインが管理画面から入らない
「返答が正しい JSON レスポンスではありません」

やっかいだけれど、無いと困る。 そういう距離感で付き合ってきました。同じような感覚の方は、少なくないのではないかと思います。

ただ、この認識には抜けているものがあります。なぜ守れるのか。そしてなぜ、正しい操作まで止めてしまうのか。 筆者はこの2つを説明できませんでした。

調べてみて分かったのは、この2つが別々の話ではないということです。WAF が持つ、たった一つの性質から、両方とも出てきます。

この記事では、まず WAF が何をしてくれるのかを見ていきます。そのうえで、情報漏洩にはどこまで効くのか、そしてなぜ正しい操作まで止めてしまうのかを順に説明します。

💡 今まさにエラーが出ていて、すぐ対処したい方へ — 原因を切り分けて、誤検知したルールだけを外すまでの手順は、実践編(前編・後編)にまとめています(近日公開)。本記事は「WAF とは何か」を理解するための入門編です。

WAF とは何か

WAF は Web Application Firewall の略です。ひとことで言えば、リクエストがアプリケーションに届く前に、1つずつ検査する仕組みです。

ブラウザ → WAF → Webサーバー → WordPress
ここで1つずつ検査される

共用レンタルサーバーで最もよく使われているのは、Apache のモジュールとして動く ModSecurity です。Plesk を採用しているサーバーなら、コントロールパネルから利用できる形で組み込まれています。

Plesk 公式ドキュメント

“The web application firewall (ModSecurity) checks all requests to your web server and related responses from the server against its set of rules.”

(Web アプリケーションファイアウォール(ModSecurity)は、Web サーバーへのすべてのリクエストと、サーバーからの対応するレスポンスを、ルールセットに照らして検査します)

— Plesk: Web Application Firewall (ModSecurity)

ここで押さえておきたいのは、WAF は WordPress の設定項目ではないということです。管理画面のどこを探しても WAF の設定は出てきません。プラグインでもありません。WordPress の外側にある、別の仕組みです。

これが後で効いてきます。原因が WordPress の外にあるとき、プラグインを停止する・テーマを切り替えるという WordPress の定石は、構造的に無力だからです。

なお、WAF はサーバー組み込み型だけではありません。CDN として前段に置くタイプや、クラウド上のロードバランサーに付けるタイプも同じ役割を果たします。置かれる場所は違っても「リクエストを検査して弾く」という本質は共通です。この記事の内容は、どのタイプにも当てはまります。また、WordPress 専用として WAF の役割を果たすプラグイン(有料)もありますが、こちらは WordPress の中で動く仕組みなので、この記事で説明する WAF とは置き場所が違います。

WAF のすごいところ

ここが本題の前半です。WAF は、知ってみるとかなり強力です。

アプリを直さずに守れる

これが WAF の本質的な価値です。通常、脆弱性を塞ぐにはコードを直すしかありません。しかし現実には、すぐに直せないことがあります。

古い WordPress で動いているが、更新すると他が壊れるので上げられない
使っているプラグインの更新が止まっていて、修正版が出ない
制作会社が既に無く、テーマのコードを触れる人がいない
脆弱性は公表されたが、修正パッチがまだ出ていない

こうした状況で、コードを一行も触らずに手を打てる層が WAF です。経路上で止めてしまえば、アプリまで攻撃が届きません。

ルールセットを選べる

ModSecurity の特徴は、検査の中身(ルールセット)を選べることです。Plesk では主に次のものが用意されています。

ルールセット Plesk 公式の説明
Atomic Basic Plesk に同梱される無償版。毎月更新
OWASP CRS 未知の脆弱性に対する汎用的な保護
Atomicorp(商用) 本番利用を推奨。日次で更新
Comodo 新しい攻撃手法を防ぐ

ここで既に、後半の伏線が出ています。OWASP CRS の説明には、公式自身がこう付け加えています。

“It is known as a very restrictive rule set; it requires additional tuning for production use.”

(非常に制限の強いルールセットとして知られており、本番利用には追加の調整が必要です)

— Plesk: Web Application Firewall (ModSecurity)

「よく効くルールほど、誤検知も増える」 という関係が、公式ドキュメントの時点で明示されているわけです。

守備範囲の広さ

守れるもの 中身
SQL インジェクション DB を不正に操作しようとする文字列
XSS ページに script を埋め込もうとする試み
既知の脆弱性を突く攻撃 公表済みの攻撃パターンにマッチするリクエスト
総当たり攻撃 ログイン試行の繰り返し
OS コマンドの注入 サーバー上でコマンドを実行させようとする文字列
ファイルの不正な読み込み サーバー内のファイルを読み出そうとする指定(../ など)
スキャナー・ボット 弱点を自動で探して回るアクセス

ここに挙げたのは代表的なものです。ModSecurity でよく使われるルールセットの OWASP CRS は、公式サイトで十数種類の攻撃を対応範囲として挙げています。WAF にはほかにもさまざまな機能がありますが、この記事では、管理画面の誤検知を理解するのに必要なところに絞って説明します。

ここまで読むと「入れておいた方がいい」と思えるはずです。実際、その通りです。問題は、この強さがどこから来ているかです。

その強さは「サイトを知らない」ことから来ている

WAF がなぜ、どんなアプリにも後付けできるのか。理由はシンプルです。

WAF は、守っているサイトのことを何も知らないからです。

WAF が見ているのは、通過していくリクエストの文字列と形だけです。知らないことを並べると、その極端さが分かります。

WAF に分かること WAF に分からないこと
どの IP から来たか その人がログインしているか
どの URL を叩いたか その人が管理者か購読者か
どんな文字列が含まれるか その操作が正当な業務かどうか
ヘッダーやボディの中身 サイトがどういう作りになっているか

ログイン状態も、権限も、操作の意図も分かりません。ただ「この文字列は攻撃のパターンに似ているか」だけを機械的に判定しています。

だからこそ、どんなアプリにも後付けできます。 WordPress だろうが自社開発のシステムだろうが、中身を知らなくても前に立てる。だからこそ速い。アプリを起動せずに判定が終わります。

この「知らないまま守る」設計が、WAF の強さの正体です。そしてそのまま、できないことの正体でもあります。

それが最もはっきり出るのが、次の問いです。

では、情報漏洩は防げるのか

ここで多くの方が気になるのが、「不正アクセスで情報を抜かれる事件が増えているが、WAF を入れれば防げるのか」という点だと思います。

半分は効きます。そして半分は、仕組み上どうやっても効きません。

止められるもの、止められないもの

攻撃の形 WAF で止められるか 理由
SQL インジェクションでデータベースを抜く 届きにくくなる リクエストの文字列に攻撃のパターンが出る
既知の脆弱性を突いて侵入する 届きにくくなる 公表済みのパターンに当てられる
ログインの総当たり 減らせる 試行を繰り返すという「形」が出る
ID を書き換えて他人のデータを見る 止められない リクエストが正常そのもの
盗んだパスワードでログインする 止められない 正規の認証に成功している
権限を持つ人が持ち出す 止められない そもそも攻撃の形をしていない
設定ミスで公開状態になっている 止められない Web 経由ですらないこともある

上半分は WAF の得意分野です。問題は下半分です。

なぜ下半分が止められないのか

たとえば、こういうリクエストを考えてみてください。

GET /mypage/order?id=1001   ← 自分の注文(正常)
GET /mypage/order?id=1002   ← 他人の注文(本来は見えてはいけない)

この2つは、文字列として区別がつきません。 1002 という値のどこにも、攻撃らしさはありません。ごく普通の数字です。

サイト側が「このログインユーザーは 1002 を見てよいのか」を判定していなければ、サーバーは何事もなく他人の注文を返します。WAF はそれを止められません。ログイン状態も、権限も、そのデータが誰のものかも知らないからです。

そして、この種の不備はWeb アプリケーションのセキュリティリスクとして最も件数が多いとされています。OWASP(Web アプリのセキュリティに関する国際的な非営利団体)が公開している「OWASP Top 10」では、アクセス制御の不備(Broken Access Control)が第1位です。その対策について、公式はこう書いています。

OWASP Top 10(A01:2021)

“Access control is only effective in trusted server-side code or server-less API, where the attacker cannot modify the access control check or metadata.”

(アクセス制御は、攻撃者がチェックやメタデータを改変できない、信頼されたサーバー側のコードまたはサーバーレス API においてのみ有効である)

— OWASP Top 10 A01:2021 – Broken Access Control

「サーバー側のコードでしか有効にならない」 と明記されています。つまり経路上に装置を置いても、ここは原理的に埋められないということです。

「出ていく側」も見てはいる

誤解のないように補足すると、ModSecurity はリクエストだけを見ているわけではありません。Plesk 公式の説明にも、レスポンスが検査対象に含まれることが書かれています。

“checks all requests to your web server and related responses from the server“

(Web サーバーへのすべてのリクエストと、サーバーからの対応するレスポンスを検査します)

— Plesk: Web Application Firewall (ModSecurity)

解析レベルを上げれば、HTTP レスポンスのボディまで見ます。

ただし、これは「個人情報の持ち出しを防ぐ機能」ではありません。 Plesk のドキュメントにも、情報漏洩対策としての説明はありません。エラーメッセージからサーバーの内部情報が漏れるといった、既知のパターンに当てはまる露出を抑えるためのものです。「顧客データが流れていくのを検知して止める」ような仕組みとは別物だと考えてください。

では、何が必要なのか

WAF は多層防御の1枚目です。入口を狭めてくれますが、それだけで漏洩が防げるわけではありません。併せて必要になるのは、たとえばこうしたものです。

アクセス制御をアプリケーション側で正しく書く — OWASP が言うとおり、ここは他の層では代替できません
認証を強くする — パスワードの使い回しを断つ、二要素認証を入れる
持っているデータを減らす — 保持しなくてよい情報は保持しない。権限は必要な人だけに
記録を残す — WAF のログは「何が来たか」の記録として価値があります

もう一点、日本で事業をしているなら知っておきたいことがあります。個人情報の漏えいは、条件に当てはまれば個人情報保護委員会への報告が義務です。要配慮個人情報が含まれる場合、クレジットカード番号など財産的被害のおそれがある場合、不正な目的によるおそれがある場合、1,000人を超える場合などが対象で、速報は3〜5日以内、確報は30日以内(不正の目的によるおそれがある場合は60日以内)と期限も決まっています。

「WAF を入れたから大丈夫」ではなく、起きたときにどう動くかまで含めて備えるのが現実的です。

「できないこと」は、欠陥ではない

ここまで読むと、WAF が頼りなく見えるかもしれません。でも、これは WAF の欠陥ではありません。

止められなかった理由を、もう一度見てください。ログイン状態を知らない。権限を知らない。そのデータが誰のものかを知らない。 だから 1002 を止められませんでした。

どんなアプリにも後付けできる理由と、他人の注文を止められない理由は、同じ一つの性質です。

これは、ひとつ前の章で見た「サイトを知らない」が、そのまま出たものです。「サイトを知らない」を無くせば、確かに漏洩には強くなります。ただしそのときには、後から足せるという WAF の長所も、一緒に消えています。 弱点だけを取り除くことはできません。

そして、この性質が困った形で出てくる場面が、もうひとつあります。守るべきものまで止めてしまうときです。

扱いにくさは、強さの裏返し

文字列だけを見て判断する、ということは、正しい操作であっても攻撃のパターンに似ていれば止まるということです。Plesk の公式ドキュメントも、この点をはっきり書いています。

“A website can stop functioning as expected.”

(Web サイトが期待どおりに動作しなくなることがあります)

— Plesk: Web Application Firewall (ModSecurity)

そのうえで、ログを分析して「過剰に制限の強いルールを切るか、サイト側を調整せよ」と案内しています。誤検知は想定外の事故ではなく、仕組み上起きうるものとして扱われているわけです。

HTML を送ること自体が、攻撃に見える

カスタム HTML ウィジェットやテキストウィジェットに HTML を書く、というのは WordPress では正当な操作です。しかし XSS を検知するルールにとって、<script> や <a href=...> を含むリクエストはまさに警戒対象そのものです。

管理者が意図して書いた HTML なのか、攻撃者が注入した HTML なのか、文字列だけでは区別がつきません。

実例:ウィジェットのエラー原因は、871 本中の 1 本

筆者が調べたケースでは、ウィジェット管理画面を開くと「『text』ブロックはエラーの影響を受けており、正しく機能しない可能性があります」という赤い帯が出ていました。

画面は普通に表示されている。上部の赤い帯だけが異常を知らせている

開発者ツールで通信を見ると、871 本のリクエストのうち、止められていたのは 1 本だけ。それが、ウィジェットの HTML 本文を送るリクエストでした。

画面本体も JavaScript も通っているので、真っ白な「アクセスが拒否されました」にはなりません。一部だけが止められると、エラー画面ではなく、原因から遠い「機能不全」として現れます。 筆者も最初は見た目で判断し、WAF ではないと結論を外していました。

💡 この1本をどうやって見つけたか、そして筆者がなぜ誤診したのかは、実践編の前編で手順と一緒に紹介しています(近日公開)。

まとめ

WAF は リクエストがアプリに届く前に検査する仕組み。WordPress の設定項目でもプラグインでもない。共用サーバーでは ModSecurity が代表的
強みは「アプリを直さずに守れる」こと。 修正パッチが出ていない脆弱性にも先に手を打てる
情報漏洩には「半分」効く。 止められるのは入口から入ってくる攻撃。正規の入口から正規の手順で出ていく情報は守備範囲外で、アクセス制御はアプリ側でしか書けない
その強さは 「サイトを知らないまま、文字列だけで判断する」 設計から来ている
扱いにくさは、その裏返し。 Plesk 公式自身が「サイトが期待どおりに動作しなくなることがある」と明記している
一部だけが止められると、エラー画面ではなく「分かりにくい機能不全」になる。筆者のケースでは 871 本中ステータスコード 403 だったのは 1 本だけ。見た目で判断すると外す

WAF は入れる価値のある仕組みです。ただ、サイトの文脈を知らないまま守る仕組みだということを理解していないと、誤検知のたびに原因が分からず時間を使うことになります。だから効くし、だから誤る——この両面をセットで覚えておくのが、一番実用的だと思います。

結局、何をすればいいのか

読む立場によって、次にやることは変わります。

セキュリティを強くしたくて読んだ方へ

WAF は有効ですが、1枚目です。入口から入ってくる攻撃には効きますが、アクセス制御の不備は塞げません。アプリケーション側の作りと、認証の強さを併せて見直してください。「WAF を入れたから大丈夫」が一番危ない状態です。

今エラーが出ていて読んだ方へ

まず回線を変えて同じ操作をしてみてください。スマートフォンのテザリングでも VPN でも構いません。結果が変わったなら、IP アドレス単位の遮断か、手元のネットワーク(社内のプロキシなど)が原因の可能性が高いです。ただし、変わらなくても WAF ではないとは言い切れません。 この記事で見てきたとおり、WAF は送った中身(文字列)でも判断するので、どの回線から送っても同じように止まることがあります。その場合は、開発者ツールで止められた通信を探すのが次の手です。どちらの手順も実践編の前編にまとめています。

まだ何も起きていない方へ

覚えておいてほしいのは一点だけです。管理画面で原因不明の不具合が出たとき、プラグインやテーマを疑う前に「経路上の仕組みかもしれない」と思い出せるか。それだけで、無駄に溶かす時間が大きく変わります。

NEXT 次回予告

実際にエラーが出ている方へ。 原因を切り分けて対処するまでの具体的な手順は、実践編(前編・後編)にまとめています(近日公開)。回線を変えて確かめる方法、開発者ツールの読み方(筆者が誤診した実例つき)、そして WAF のログでルール ID を特定し、そのルールだけを外す方法まで扱います。