WordPress: xmlrpc.phpとは?サイトに必要かどうかを判断するための知識

xmlrpc.phpは脆弱性が指摘されていて、無効化するべきという声が多いです。
そういわれると自分も無効化しようと思うのですが、どんな脆弱性があるのか理解しないと気持ちが悪いです。
というかxmlrpc.phpが何をしているのかも知りたい。

そこで、いろいろ調べてみました。

xmlrpc.phpの役割

xmlrpc.phpは、WordPressの管理画面を経由させることなく、WordPressを操作できるプログラムです。

WordPressで記事を登録する場合、通常は投稿画面で記事を入力します。
すると、入力した記事はデータベースに保存されます。
そしてスマホやパソコンのブラウザから記事のデータを送るように要求されると、データベースから記事のデータを取り出してWebページのデータを作成して、スマホやパソコンに送り返します。

xmlrpc.phpは、投稿画面を開かなくてもデータベースに記事を登録することができます。

仕組みとしては、「ユーザー名」と「パスワード」および「記事データ」を受け取り、「ユーザー名」と「パスワード」が正しいものかを確認します。
正しかったら「記事データ」をデータベースに登録します。
正しくなかったら、「ユーザー名」と「パスワード」が正しくないという情報を送り返します。

xmlrpc.phpの解説

これをうまく利用すると、利便性が向上します。
例えばWordPressの投稿画面が使いにくいという人なら、自分の使いやすいアプリで記事を作成することができます。

またxmlrpc.phpは投稿だけでなく、記事削除や編集、コメントの管理、ピンバックの受信などを、管理画面を介さないでおこなうことができるようになっています。

xmlrpc.phpの脆弱性

脆弱性という言葉には、二つの側面があります。

  1. プログラムの不具合(バグ)
    バグがあることで、意図しない情報開示やデータ改ざんなどをしてしまうものです。
    このケースでは修正されたプログラムが提供されるのを待ち、更新することで対処します。
  2. 設計上のミス
    プログラムの作成者が見落としていたプログラムの盲点をついたものです。
    こちらもプログラムを修正することで盲点を解消するのが望ましいですが、場合によってはプログラムの根本的な考え方から修正する必要があります。
    このようなケースでは、プログラムそのものの廃止を検討する事態まで発展することもあります。

xmlrpc.phpは過去には一つ目の脆弱性があったようですが、現在問題になっているのは二つ目のケースです。

例えば、xmlrpc.phpを使用するとユーザー名とパスワードを取得できるという脆弱性があります。
方法はとても単純です。

xmlrpc.phpを使用したID・パスワード取得
  1. 適当なユーザー名とパスワードでxmlrpc.phpにデータを送る
  2. 認証に失敗したという通知を得たら、別のユーザー名とパスワードを送る
  3. 認証に成功するまで繰り返す

時間がかかりますが、いつかは正解を得ることができます。
この方法はブルートフォースアタックと呼ばれています。
無限に繰り返すとか気の長い話ですが、攻撃者は同時に複数のサイトを攻撃しています。
そのうちのいつくかで結果が出ればいいので、コンピューターに自動処理をさせて放置しているのです。

実はこの脆弱性は、ログイン画面にもあります。
同様の手法で、いつかはIDとパスワードを取得できます。

しかしログイン画面はキャプチャ画像などを利用した”人が操作する必要がある”仕組みが導入されていることが多いことと、さらに、WordPress側がxmlrpc.phpのセキュリティ強化に消極的なことからまずはxmlrpc.phpが狙われるのです。

xmlrpc.phpとDDos攻撃

前項の脆弱性は、被害者となるケースでした。
しかし、場合によっては加害者となるケースがあります。

xmlrpc.phpのPingback機能を悪用すると、WebサイトをDDos攻撃の踏み台として利用することができます。

DDos攻撃はDos攻撃の一種です。
Dos攻撃とはサーバーに短期間のうちに大量のリクエストを投げつけて、サーバーの負担を増大させ、正常な処理を妨げるのを目的とした攻撃です。
お気に入りのホームページを見ようとしたら、いつまでたっても表示しれくれないと思ったらエラーが表示された。
こんなときは、サーバーがDos攻撃されている可能性があります。

Dos攻撃のイメージ

そしてDDos攻撃は、大量のコンピューターから一斉に一台のコンピューターに負荷を与える攻撃です。
その手法として第三者のコンピューターを乗っ取ったり、プログラムの脆弱性を利用したりします。

WordPressでよく話題としてあがるのが、Pingback機能でのDDos攻撃です。
Pingback機能は自分のサイトから他のサイトにリンクを貼ったとき、そのサイトに「リンクを貼ったよ」と通知する機能です。

当然のことですが、他のサイトからもPingbackが送られてきます。
この通知はxmlrpc.phpで受け取ります。
サイトと関係ない第三者からの通知なので、ユーザー名とパスワードのチェックはありません。
どんなものでも受け入れます。
そして通知元の記事に、本当にリンクが貼ってあるのか確認します。

Pingbackの処理の流れ

この流れに脆弱性があります。

攻撃者が世界中のWordPressサイトに、「〇〇というサイトであなたの記事のリンクを貼ったよ」と通知します。
すると世界中にサイトが、〇〇というサイトで本当にリンクが貼られたのか確認します。
そのサイトは同時に大量のリクエストを受け取ることになり、正常な処理ができない事態に陥るのです。
Pingbackを受け取ったサイトは、攻撃の踏み台として利用され、DDos攻撃が成立してしまうのです。

PingbackでのDDos攻撃イメージ

このとき攻撃を受けた側からみると、攻撃したのは記事のデータを要求したコンピューターです。
攻撃したつもりがなくても、加害者となってしまうのです。

xmlrpc.phpの脆弱性対策

外部アプリの連携やPingbackなどxmlrpc.phpは便利な機能を提供してくれます。
その反面、セキュリティ上でのリスクが高まるというデメリットがあります。

xmlrpc.phpの脆弱性対策として、複数ある機能のうち問題のありそうなものだけ無効化する方法があります。
しかし実情としては、xmlrpc.phpそのものを無効化することが望ましいです。

現状では外部アプリの連携はxmlrpc.phpからREST APIという機能に置き換わっています。
外部アプリとの連携という意味では、xmlrpc.phpは過去のものになっているのです。

またPingback機能は以前は自動で相互リンクを自動的に生成できるものとして、とても有意義な機能でした。
しかし実際にPingbackとして送られてくるのは、ほぼスパムです。
自サイトにリンクが貼られたと喜んで相手のサイトを確認したら、怪しいサイトに飛ばされるケースがほとんどです。

このようなことから機能を個別に制限するのではなくて、xmlrpc.phpそのものを無効化することが望ましいです。

プラグインでの対策

xmlrpc.phpを無効化するのは、次のプラグインを入れてしまうのが一番簡単です。

SiteGuard WP Plugin

プラグインのXMLRPC防御機能を開き、XMLRPC無効化を選択します。

XMLRPC防御

手動での対策

WordPressはインストールしたプラグインが脆弱性を持っていることが多いです。
セキュリティ向上のために導入したプラグインに脆弱性がある可能性は、ゼロではありません。
今のところ前項で紹介したプラグインに脆弱性はなさそうですが、それでも心配だという人は自分でアクセス制限をしましょう。

今回は2つの方法を紹介します。

方法1:.htaccessを編集する

.htaccessファイルに次のコードを記述します。

  • <Files xmlrpc.php>
  • Order Deny,Allow
  • Deny from All
  • </Files>
AFFS Simple Code Viewer
Copy

これでxmlrpc.phpにアクセスすると、403エラーになります。

注意点は.htaccessファイルを開くと次のような記述があるので、これの前に記述します。

  • <IfModule mod_rewrite.c>
  • RewriteEngine On
  • RewriteBase /
  • RewriteRule ^index\.php$ - [L]
  • RewriteCond %{REQUEST_FILENAME} !-f
  • RewriteCond %{REQUEST_FILENAME} !-d
  • RewriteRule . /index.php [L]
  • </IfModule>
AFFS Simple Code Viewer
Copy

方法2:function.phpを編集する

レンタルサーバーなどで.htaccessを編集できないときは、function.phpや自作プラグインに、次のコードを記述します。

  • if( defined( 'XMLRPC_REQUEST' ) ){
  • header('HTTP/1.1 403 Forbidden');
  • exit;
  • }
AFFS Simple Code Viewer
Copy

この方法はxmlrpc.phpを実行するので、xmlrpc.phpを実行しない方法1と比較すると効率が悪いです。

簡単なコード解説

xmlrpc.phpは最初に定数XMLRPC_REQUESTを定義します。
function.phpでこの定数を確認したら、403を送信して終了しています。

上のコードはプログラムの流れを強制的に中断しているので、少し強引かもしれません。
次のコードは、プログラムを中断することなく最後まで実行してくれます。

  • add_filter('wp_xmlrpc_server_class', 'my_xmlrpc_server_class');
  • function my_xmlrpc_server_class(){
  • return 'my_wp_xmlrpc_server';
  • }
  • class my_wp_xmlrpc_server{
  • public function serve_request(){
  • header('HTTP/1.1 403 Forbidden');
  • }
  • }
AFFS Simple Code Viewer
Copy
簡単なコード解説

xmlrpc.phpはリクエストを実際に処理するクラスをwp_xmlrpc_server_classフィルーターで取得し、そのクラスのserve_requestメソッドを実行します。
そこで、独自のクラスを定義して、そのクラスに403をヘッダー送信するserve_requestメソッドを定義しています。