WordPressは、REST APIにとって代わられたXML-RPCをサポートしています。しかしこれは不正アクセスでよく使われる技術。
古い技術は狙われやすい、はっきりと下位互換の目的がないかぎり拒否設定をしよう、という話をWebサーバーのアクセスログを見ながら説明します。
XML-RPC(XML - Remote Procedure Call)って何?
RPC (Remote Procedure Call) はリモートでプログラムを動かす技術で、XML-RPCは通信のやり取りをXML形式で行うもの。
プロシージャとサブルーチン
プロシージャ(procedure)は一般的に『手続き』と呼ばれる。プログラムをまとめて特定の機能をもっているもの。
サブルーチン(subroutine)もプログラムをまとめて特定の機能をもっているが、『特定の処理』の意味合いが強く、機能をもってなくても使われる。
"routine" は『決まりきった仕事。いつもの手順』なので、繰り返し使う、共通化されたプログラムという意味もある。
プロシージャ ≒ サブルーチン ではあるが、機能はプログラムを組み立てて作るので、プロシージャのほうが概念としては大きい。
(プロシージャはサブルーチンの集まりでもある。)
後から出てきたREST APIは同じような技術。WebのHTTP/HTTPS通信ではREST APIを使うようになりXML-RPCは古い技術になってきました。
WordPressでもREST APIがメインになっています。編集ページで使うエディタのGutenbergは、REST APIの集合体と言っていいほど。
REST API (Representational State Transfer API)
URLを指定すると常に同じ結果を返すAPI。
URLはユニークで、決まった処理のリクエストになるので、シンプルでわかりやすいのが特長。
処理を受けるサーバーも、URLを見れば何をすれば分かるのでシンプルで実装しやすい。
結果は、HTML, XML, JSONなどで返す。
最近のWebサービスで提供されるAPIはREST APIが多い。
Facebook, Twitterなどもそう。また、ECサイトと在庫管理などのWebサービスと連携するときにもREST APIを使う。
Webサービスでは情報取得、情報の追加・更新・削除などのAPIが提供されるが、その説明にURLを指定するものはREST APIであることが多い。
もうひとつ、セッションを使わないのが特長。
セッションを使わずに1リクエストで処理が完結するため、アクセス数やリクエスト数の多いサイトに適している。(SNSなど)
セッションハイジャックがないので、情報漏えいや不正なリクエストも防ぐことができる。
と思うところですが、そこはむずかしいところです。
WordPressは古いバージョンのユーザーがある一定数いる以上、切り捨てることができません。XML-PRCの機能を残しているのは下位互換のためです。それ以外の意味はありません。
プラグインやテーマで下位互換以外の目的で実装しているものは危険。
もう辞め時を探ってるのかもしれません。たんにやる気がないだけかも。
だとしたらセキリティに対する意識が高いとは言えません。代替手段を考えたほうがいいでしょう。
xmlprcはよく知られたWordPressの脆弱性
新しいものに取って代わられた技術は狙われやすいというのが相場です。xmlprcも例外なく。
xmlrpcを開けたままにしていたときのWebサーバーのログがこれ。
0.452 - - XXX.XXX.XXX.XXX - - [17/Apr/2021:06:23:14 +0900] "POST //xmlrpc.php HTTP/1.1" 200 415 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.193 Safari/537.36" "-"
0.375 - - XXX.XXX.XXX.XXX - - [17/Apr/2021:06:23:14 +0900] "POST //xmlrpc.php HTTP/1.1" 200 415 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.193 Safari/537.36" "-"
・
・
・
0.329 - - XXX.XXX.XXX.XXX - - [17/Apr/2021:06:39:20 +0900] "POST //xmlrpc.php HTTP/1.1" 200 512 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.193 Safari/537.36" "-"
0.299 - - XXX.XXX.XXX.XXX - - [17/Apr/2021:06:39:21 +0900] "POST //xmlrpc.php HTTP/1.1" 200 512 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4240.193 Safari/537.36" "-"
不正アクセスの痕跡からxmlrpcの部分をお見せしてますが、15分間に1000回以上のアクセスが行われました。
POSTリクエストなのでログには見えませんが、ユーザー名・パスワードを指定したブルートフォースアタックです。
(その前にユーザー名を取ろうとしている痕跡もあるので想像できる。)
ブルートフォースアタック(総当り攻撃)
ユーザー名やパスワードなどを大量に作成し、サービスのログインを試みる攻撃。
不正ログインのための情報解析をかんたんにできる初歩的な手法。
初歩的な手法なので対応策もよく知られる。
- ログイン制限(3回失敗するとしばらくログインできない。解除が必要など)
- 2段階認証(安易な手法を使うぐらいなのであきらめも早い。)
半年分のログをチェックしましたが、xmlrpcを使っているのはJetpackプラグインだけでした。
xmlrpcを無効化してどれだけ影響があるか?
xmlrpcを使っているものがどれだけあるのか、それぞれの環境にもよります。たまたまボクが見た環境がJetpackだっただけで。
Jetpackには、WordPressアカウントを作るとhttps://wordpress.comからWordPressの管理機能が使えるようになります。見たところ、xmlrpcを無効化して影響が出るのは、https://wordpress.comへログインしたときだけでした。
具体的には記事作成などの管理機能が使えなくなること、WordPressアカウントと自サイトの連携マークが切断状態になることくらい。
WordPressアカウントと自サイトの連携はつながっています。WordPressの管理画面からJetpackのダッシュボードを確認したらつながってました。
xmlrpcからの疎通を一部止めたために、Wordpressアカウント(wordpress.com)での機能の一部が使えなくなって連携不可のマークが表示されたみたい。
WordPressの管理機能をあえてwordpress.comでする必要はないので影響なしと判断した。
どうやらxmlrpcからの疎通を止めたために、連携はできてないと認識されたらしい。WordPressの管理機能をあえてhttps://wodpress.comで使う理由はないので影響なしと判断しました。
Webサーバーで無効化
xmlrpcの拒否設定はWebサーバーで行うほうが良いです。WordPressでしてもいいですが、WebサーバーからWordPressのPHPプログラムへ処理を移譲する負荷は馬鹿にならないので。
Webサーバーがリクエストを受信。
↓
WebサーバーからPHP(Wordpress)起動。これが無駄
↓
WebサーバーがPHPからレスポンスを受け取る。これが無駄
↓
Webサーバーがレスポンスを返す。
Nginxの拒否設定
server {
# 追加
# ブルートフォースアタック対応
location ~* /xmlrpc\.php$ {
return 444;
}
}
/etc/nginx/ 下にある ***.confファイルの serverセクションに、xmlprc.phpのリクエストは444を返す処理を追加します。
ステータスコード444はHTTPステータスにないものでNginxが独自に設定したもの。444はリクエストを受けるだけでレスポンスを返しません。
404(Not Found)などでもいいですが、これらは一応、レスポンスを返します。その分だけ通信トラフィックが発生するのでNginxでは444を使いましょう。
ブラウザからアクセスするとサイトが無いかのように表示されます。
メッセージを見て『サイトが無くなった!』と勘違いしそうですが、xmlrpc.phpだけ拒否っているのでサイト自体は存在します。
あと、設定ファイルの反映も忘れずに。
systemctl reload nginx
Nginxは .htaccessを使いません。.htaccessはApache HTTPサーバーの設定ファイルです。
Apache HTTP (.htaccess) の拒否設定
Webサーバーのアクセス設定でよく見られるのは .htaccessに書き込むことです。ボクは444ステータスがあることや総合的なパフォーマンスからApacheを使ってないんですが、利用者はこっちのほうが多いのかな?
<Files xmlprc.php>
Order allow,deny
Deny from all
</Files>
この設定は403(Forbidden)を返します。
今のレンタル/クラウド/VPSサーバーでは、管理画面で.htaccessファイルを編集する機能がついているので馴染みがあるでしょう。
リクエスト拒否設定の方法は基本的に同じ。
拒否設定の説明文はwlwmanifest.xmlのときと同じです。
このページを書く際もパクってコードのファイル名を変えただけ。それくらい同じ作業。
このやり方は覚えておきましょう。いくらでも応用が効きます。
ちがいがあるとすれば、HTMLの<head>に<link rel=... />で追加されることがあるくらい。wlwmanifest.xmlはこのパターンでHTMLからも削除しました。