XML-RPCってそもそも何者?
まず「XML-RPCって何?」からいきましょう。
WordPress のルートにある xmlrpc.php というファイル、見たことありますよね。
これはざっくり言うと、
外部のアプリやサービスから
WordPress に「リモート操作」するための入口
です。
昔は、
スマホアプリから記事を投稿する
外部ツールからブログを更新する
といった用途でよく使われていました。
今でも一部のツールや、Jetpack などのプラグインが利用することがありますが、
多くのサイトでは「存在はしているけど、実は使っていない」状態になっています。
なぜXML-RPCがセキュリティ的に問題になりやすいのか
ログイン試行を“まとめて”投げられてしまう
XML-RPC の大きな問題のひとつは、
1回のリクエストで、複数のログイン試行をまとめて送れる
という仕様があることです(system.multicall)。
通常のログインフォーム(/wp-login.php)だと、
1回のリクエストで1回のログイン試行
→ ログイン試行回数制限プラグインなどで防御しやすい
という構造になっています。
ところが XML-RPC 経由だと、
1リクエストで何十回分ものログイン試行
=総当たり攻撃(ブルートフォース)に悪用されやすい
という状態になります。
つまり、
表のログイン画面は守っているつもりでも
裏口の XML-RPC からパスワード総当たりをされる
ということが起こり得ます。
DDoS やリフレクション攻撃にも悪用されることがある
XML-RPC は、
外部からリクエストを受けて
WordPress が何らかの処理をして
レスポンスを返す
という仕組みなので、
大量のリクエストを投げられると、サーバー負荷の原因にもなります。
また、他サイトへの攻撃の踏み台として悪用されるケースもあり、
「使っていないのに開けっぱなしにしておくと、余計なリスクを抱える入口」になりがちです。
まず考えるべきこと:「自分のサイトはXML-RPCを本当に使っているか?」
使っているケースの例
例えば、こんな場合はXML-RPCが使われている可能性があります。
スマホアプリ(公式WordPressアプリなど)から投稿している
Jetpack など、一部の外部連携プラグインを使っている
外部のブログクライアント(MarsEdit など)から更新している
こういう運用をしているなら、
XML-RPC を完全に止めると、その機能が動かなくなる可能性があります。
まったく心当たりがないなら「たぶん使っていない」
逆に、
更新は全部ブラウザから
外部ツールやアプリは使っていない
Jetpack も入れていない
というサイトなら、
XML-RPC を使っている可能性はかなり低いです。
この場合、
「使っていない入口を開けっぱなしにしている」
状態なので、
思い切って閉じてしまう(アクセス制御する)候補になります。
XML-RPCの「アクセス制御」とは何をするのか
完全に遮断する/一部だけ許可する
XML-RPC のアクセス制御には、ざっくり2つの方向性があります。
完全に遮断するxmlrpc.php へのアクセスをすべて拒否する
一部だけ許可する
特定のIPやサービスからのアクセスだけ許可し、それ以外は拒否する
どちらを選ぶかは、
自分のサイトがXML-RPCを使っているか
使っているなら、どのサービスからだけか
によって決めるイメージです。
「アクセス制御」はアプリ側ではなくサーバー側でやるのが基本
XML-RPC のアクセス制御は、
WordPress の中の設定
ではなく
Webサーバー(Apache / Nginx)の設定
で行うのが基本です。
理由はシンプルで、
WordPress に処理を渡す前に
「このリクエストはそもそも通さない」と判断できるから
です。
プログラミングの感覚で言えば、
アプリケーションの前に立つフィルターで
特定のエンドポイントへのアクセスをブロックする
という設計です。
例題:XML-RPCを完全に止めた場合のイメージ
Before:開けっぱなしの状態
https://example.com/xmlrpc.php にアクセスすると、
何らかのレスポンスが返ってくる
(エラーでも「XML-RPCとして反応している」状態)
攻撃者はここに対して、
ログイン総当たり
DDoS 的な大量リクエスト
などを投げることができます。
After:アクセス制御で遮断した状態
同じURLにアクセスすると、
403 Forbidden(アクセス禁止)
あるいは
404 Not Found(存在しない扱い)
などが返ってきて、
WordPress の XML-RPC 処理に到達しない状態になります。
攻撃者からすると、
「このサイトは xmlrpc.php が使えないな。ここから攻撃するのは無理だ」
という状況になります。
「完全遮断」と「部分的に許可」の使い分け
完全遮断が向いているケース
次のようなサイトは、完全遮断がかなり有力な選択肢です。
更新はすべてブラウザから
スマホアプリや外部クライアントは使っていない
Jetpack など XML-RPC に依存するプラグインも使っていない
この場合、
xmlrpc.php は「使っていないのに開いている裏口」
なので、閉じてしまっても実害はほぼありません。
セキュリティ的には、
攻撃面(Attack Surface)を1つ減らせる
ログイン総当たりのルートを1つ潰せる
という、コスパの良い対策になります。
部分的に許可が向いているケース
一方で、
どうしてもスマホアプリから投稿したい
Jetpack の機能を使いたい
といった場合は、
完全遮断ではなく「部分的に許可」という選択肢もあります。
例えば、
特定のIPレンジ(Jetpackのサーバーなど)からのアクセスだけ許可
それ以外のIPからの xmlrpc.php へのアクセスは拒否
といった形です。
これは少し高度な設定になりますが、
「必要なサービスだけ通し、それ以外は閉じる」
という、より洗練されたアクセス制御になります。
プログラミングの感覚で捉える「XML-RPCのアクセス制御」
これは「使っていないAPIエンドポイントを閉じる」話
Webアプリケーションの開発では、
使っていないAPIエンドポイント
デバッグ用に残っていたエンドポイント
などを、本番環境では閉じるのが基本です。
XML-RPC は、WordPress にとっての「古いAPIエンドポイント」のようなものです。
今も明確に使っているなら、
ちゃんと守りながら使えばいい。
でも、
使っていないのに開けっぱなし
存在すら意識していなかった
という状態なら、
「そのエンドポイントは閉じる」
というのが、エンジニアとして自然な判断です。
「攻撃されないようにする」ではなく「攻撃の入口を減らす」
セキュリティの基本のひとつは、
攻撃されないように頑張る
だけでなく
攻撃されうる入口そのものを減らす
という発想です。
XML-RPC のアクセス制御は、
ログインURLを守る
パスワードを強くする
といった「守る」系の対策に加えて、
そもそも攻撃に使われやすい入口を1つ減らす
という、攻撃面(Attack Surface)を削るための一手です。
まとめ:XML-RPCのアクセス制御は「使っていない裏口を閉じる」発想
「XML-RPCのアクセス制御」というテーマの本質は、
xmlrpc.php という“リモート操作用の入口”に対して
本当に必要なアクセスだけを許可し、それ以外を閉じる
ということです。
押さえておきたいポイントは、
まず「自分のサイトがXML-RPCを使っているか」を確認する
使っていないなら、思い切って完全遮断する選択肢がある
使っているなら、必要な範囲だけ許可する形も検討できる
という3つです。
一度、自分のサイトで https://あなたのドメイン/xmlrpc.php を開いてみてください。
「これ、そもそも本当に必要?」と問い直すことから、
あなたのWordPressのセキュリティ設計は、また一段深くなっていきます。


