WordPress のサイトを点検していて、ログインしていない人でも、ユーザーの一覧を取れる状態になっていることに気づきました。標準の REST API の /wp-json/wp/v2/users です。
筆者のサイト(BLST VPN Navi)は、ネットの「見られる・盗まれる・つながらない」という悩みに、各社の公式の案内と毎日取得する料金データで答えるガイドです。紹介しているサービスの一部からアフィリエイト報酬を受け取っています。この記事は技術的な話で、特定のサービスをすすめるものではありません。
何が見えていたか
ブラウザで次の URL を開くだけで、記事を書いたことのあるユーザーの一覧が JSON で返ってきました。
https://example.com/wp-json/wp/v2/users
返ってくる項目には、表示名のほかに slug があります。slug は著者ページの URL に使われる値で、初期設定ではログイン名から作られます。
[
{ "id": 1, "name": "表示名", "slug": "login-name", "link": "https://example.com/author/login-name/" }
]
ログイン名が分かると、不正ログインを試す側は「パスワードだけ当てればいい」状態になります。わざわざ渡す必要のない手がかりです。
塞ぎ方
ユーザーの一覧を見る権限(list_users)がある人にだけ、この窓口を返すようにしました。テーマを替えても外れないよう、mu-plugins に置いています。
<?php
/**
* Plugin Name: 公開範囲の制限
* Description: 外から見える必要のない情報を、ログインしていない人に返さない。
*/
if (!defined('ABSPATH')) exit;
add_filter('rest_endpoints', function ($endpoints) {
if (current_user_can('list_users')) return $endpoints;
foreach (array_keys($endpoints) as $route) {
if (preg_match('#^/wp/v2/users(/|$)#', $route)) unset($endpoints[$route]);
}
return $endpoints;
});
ログインしていない人が開くと、rest_no_route(404)が返ります。
管理画面には影響しない
ブロックエディタの「投稿者」の選択などは、この窓口を使います。ただし管理画面では、ユーザーの一覧を見る権限のある人がログインしているので、今までどおり使えます。
ほかにも見ておくところ
ログイン名の手がかりは、この窓口だけではありません。点検したときは、次も確かめました。
| 場所 | 確かめること |
|---|---|
/?author=1 |
著者ページに転送され、URL にログイン名由来の slug が出ないか |
| 著者ページの URL |
/author/login-name/ の形になっていないか |
| 記事の HTML・RSS | 著者のクラス名やフィードに、ログイン名が出ていないか |
readme.html・license.txt
|
WordPress の版がわかるファイルを、外から開けないようにしているか |
slug をログイン名と違う値にしておくと、この窓口や著者ページから分かるのは表示用の名前だけになります。
まとめ
-
/wp-json/wp/v2/usersは、初期状態ではログインしていない人にも返る -
rest_endpointsのフィルターで、list_usersの権限がある人にだけ返すようにする - 著者ページの URL や
slugから、ログイン名が分からないようにしておく