自分のブログを開いたら、画面の上に「投稿を編集」のボタンが出ていた。
「えっ、これ、みんなに見えてる?」と焦って、この記事にたどり着いた人もいると思います。

先に結論を書くと、そのボタンは、ログインしている自分にしか見えていません。私も同じことで焦りましたが、結局そうでした。

ただ、調べていく途中で別のものが見つかりました。私のブログでは、WordPressのログイン名が、誰でも見られる状態になっていました。特別な道具はいりません。ブラウザでURLを1本打つだけで読めます。

私はセキュリティの専門家ではありません。ログイン名が見えるとまずい、というのも、知識として知っていたわけではなく、直感で「これは嫌だな」と思っただけです。
この記事は、自分のサイトで同じ状態になっていないかを確かめる方法と、私が実際に塞いだ5つの入口、そのとき踏んだ失敗を、順番に並べた記録です。


「えっ、みんなに見えてる?」から始まった

ある日、自分のブログを検索して開いたら、記事の上に黒いバーが出ていて、「投稿を編集」のボタンまで並んでいました。
誰でも記事を書き換えられる状態になっている、と思いました。正直、かなり焦りました。

正体は、WordPressの管理バー(ツールバー)です。ログインしている人にだけ表示されるもので、ブログを書いている本人のブラウザには出ますが、訪問者には出ません。

まずやることは1つだけです。ログインしていないブラウザで、同じページを開いてみてください。

私はスマホで確かめました。パソコンでログインしていても、スマホのブラウザではログインしていなかったので、そこで開けば訪問者と同じ画面になります。スマホでは、バーもボタンも出ていませんでした。
パソコンしかない場合は、ブラウザのシークレットウィンドウ(プライベートウィンドウ)で開けば同じことが確かめられます。

それでも念のため、AIにも聞きました。スクショを見せて、ログインしていない状態で返ってくるページの中身を調べてもらうと、編集用のリンクは1つも入っていませんでした。ここで、管理バーの件は「問題なし」で終わりました。

問題は、そのついでに見つかったほうです。


調べてみたら、本当に見えていたのはログイン名のほうだった

管理バーを調べているとき、AIから「ついでに、ログイン名が外から見えていないかも確かめましょう」と言われました。
試してみると、見えていました。

確かめ方は簡単です。ログインしていないブラウザ(スマホやシークレットウィンドウ)で、次の2つのURLを開くだけです。example.com のところは、自分のブログのアドレスに置き換えてください。

① これを開いて、アドレスバーを見る

https://example.com/?author=1

開くと、アドレスが勝手に https://example.com/author/〇〇/ に変わることがあります。
この 〇〇 が、ログイン名です。

② これを開いて、自分のログイン名を探す

https://example.com/wp-json/wp/v2/users

英語と記号だらけの画面が出ます。読めなくて大丈夫です。
ブラウザの「ページ内検索」で、自分のログイン名を打ち込んでみてください。見つかったら、見えています。

私のサイトでは、①でも②でも、ログイン名がそのまま出てきました。

ほかにも出口は3つあった

この2つを塞いで終わり、ではありませんでした。同じログイン名が、ほかにも3か所から読めました。

  • ①で飛ばされた先の「著者ページ」
  • 記事をほかのサイトに埋め込むときに使われるデータ
  • WordPressが自動で作るサイトマップ(これは最初見落としていて、あとで気づきました)

どれも、ふつうにブログを書いているだけでは目に入らない場所です。

なぜログイン名が出てしまうのか

WordPressは、著者ページのアドレスを作るときに、何も設定していなければログイン名をそのまま使います。
そのアドレスが、上のいろいろな場所に載っている。だからログイン名が見える、という仕組みです。

私が何か設定を間違えたわけではなく、WordPressを入れたままの状態でこうなっていました。


WordPress公式は「ユーザー名は秘密じゃない」と言っている

ここで、正直に書いておくことがあります。

WordPressを作っている開発チームは、「ユーザー名やユーザー番号は、秘密の情報として扱っていない」と公式の文書ではっきり書いています。さっきの②のURLでユーザーが見えるのも、うっかりではなく、わざとそういう作りにしているそうです。

開発チームの考え方はこうです。

  • ユーザー名は「誰か」を示す名札のようなもの
  • 本人かどうかを確かめるのは、パスワードの役目

家にたとえると、表札は外から見えて当たり前で、守るのは鍵のほう、という話です。

なので、ログイン名が見えていたからといって、すぐに乗っ取られるわけではありません。ここは安心してください。

それでも塞いだ理由

じゃあ放っておいていいのか、というと、私は嫌でした。理由は直感です。

ログイン名が分かれば、悪い人が試すのはパスワードだけになります。鍵は守るとしても、わざわざ表札に「合鍵の形はこれです」と半分書いておく必要はない、と思いました。
専門的な根拠があったわけではありません。「自分の家の表札に、余計なことは書きたくない」くらいの気持ちです。

本当の守りは、パスワードとログイン画面のほう

ここは公式の考え方に従います。ログイン名を隠すより先に、こちらができているかを確かめてください。

  • パスワードは長く、ほかのサイトと使い回さない
  • ログイン画面を守るプラグインを入れる

私は「SiteGuard WP Plugin」を入れていて、次の設定が効いています。

  • ログイン画面のアドレスを、初期のものから変えてある
  • ログイン画面に、ひらがなの画像認証を出す
  • パスワードを3回まちがえたら、しばらくログインできなくする
  • 誰かがログインしたら、メールで知らせる

ログイン名を隠すのは、この上に乗せる「おまけの一枚」くらいに考えています。


塞いだ方法:テーマではなく「mu-plugins」に置いた

ここからは、私が実際にやったことです。
コードはAIに書いてもらいました。私が決めたのは「どこに置くか」と「何は止めないか」の2つです。

置き場所:functions.phpには書かなかった

こういう対策を調べると、よく「テーマの functions.php に追記しましょう」と出てきます。
でも、私はそこに書きませんでした。

私のブログのテーマ(JIN)には、子テーマを作っていません。この状態で functions.php に書き足すと、テーマを更新したときに上書きされて、書いたものが消えます。消えたことに気づかないまま、穴が開きっぱなしになるのが一番怖いと思いました。

そこで使ったのが mu-plugins というフォルダです。

  • 場所は wp-content/mu-plugins/(無ければ自分で作る)
  • ここにPHPファイルを1つ置くだけで、自動で有効になる
  • テーマを更新しても消えない
  • 管理画面から「停止」もできない(うっかり止める心配がない)

私はAIにSSHで置いてもらいましたが、ConoHa WINGならファイルマネージャーからでも置けます。

止めないもの:REST API全体は止めない

調べると「REST APIをまるごと止めればいい」という方法も出てきます。これはやめました。

REST APIを止めると、お問い合わせフォーム(Contact Form 7)が送信できなくなり、記事を書く画面(ブロックエディタ)も動かなくなります。ブログが書けなくなっては本末転倒です。
なので、止めるのはユーザー一覧の部分だけ、それもログインしていない人に対してだけにしました。

実際のコード(4か所ぶん)

wp-content/mu-plugins/yurutto-hardening.php という名前で置いています。前の章で書いた出口のうち、4つをこれで塞ぎました。

<?php
/**
 * Plugin Name: ログイン名を外に出さない
 */

if (!defined('ABSPATH')) {
	exit;
}

// 1) ユーザー一覧(/wp-json/wp/v2/users)を、ログインしていない人には出さない
//    REST API 全体は止めない(お問い合わせフォームと編集画面が動かなくなるため)
add_filter('rest_endpoints', function ($endpoints) {
	if (is_user_logged_in()) {
		return $endpoints;
	}
	unset($endpoints['/wp/v2/users']);
	unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
	return $endpoints;
});

// 2) /?author=1 と著者ページを、トップページへ転送する
//    WordPress がログイン名入りのアドレスへ転送するより先に動かすため、優先度を 0 にしている
add_action('template_redirect', function () {
	if (is_admin() || is_user_logged_in()) {
		return;
	}
	if (isset($_GET['author']) || is_author()) {
		wp_safe_redirect(home_url('/'), 301);
		exit;
	}
}, 0);

// 3) 埋め込み用データから、著者の名前とアドレスを消す
add_filter('oembed_response_data', function ($data) {
	unset($data['author_name'], $data['author_url']);
	return $data;
});

著者ページはトップへ転送しています。一人で書いているブログなので、著者ページが無くても困る人はいません。複数人で書いているブログなら、ここは事情が変わります。

置いたあとは、前の章の①と②をもう一度、ログインしていないブラウザで開いて確かめました。①はトップページに戻されました。

②は、こんな一行だけが出るようになりました。

{"code":"rest_no_route","message":"URL \u3068\u30ea...","data":{"status":404}}

\u3068 のような記号は、日本語の文字を記号で書いたものです(中身は「一致するルートが見つかりませんでした」)。ブラウザによっては、このまま記号で表示されます。
rest_no_route と 404 が見えていれば、塞げています。


ハマったところ:5つ目の出口はサイトマップにあった

4か所を塞いで安心していたら、2日後にGoogleからメールが来ました。
Search Console(Googleの検索の管理画面)からの「インデックスに登録されないページがあります」という知らせです。

調べてみると、引っかかっていたのは著者ページでした。前の章でトップへ転送した、あのページです。
Googleがこのページを見に来たのは、転送を入れる前でした。なので、通知そのものは古い情報で、困ることはありませんでした。

ただ、「Googleはなぜ著者ページを知っていたのか」を追いかけたところで、5つ目の出口が見つかりました。
WordPressが自動で作るサイトマップに、著者ページのアドレスがそのまま載っていたんです。ページ自体は転送していても、サイトマップを開けばログイン名が読めます。

失敗その1:サイトマップを外したら、トップページが返ってきた

最初は、サイトマップから「ユーザー」の1枚を外す設定だけを入れました。
すると、/wp-sitemap-users-1.xml を開いたときに、「見つかりません」ではなく、なぜかトップページが表示されるようになりました。

WordPressは、外したサイトマップを聞かれると「何も返さずに素通り」するだけで、そのまま普通のページを出してしまう作りでした。
Googleから見ると「中身のないアドレスなのにトップページと同じものが出る」状態で、検索にとってはよくありません。なので、ここははっきり「見つかりません(404)」を返すように書き足しました。

失敗その2:サイトマップの目次ごと消した

ここで本番のサイトを壊しました。

「無いサイトマップは404にする」と書いたら、サイトマップの目次 /wp-sitemap.xml まで404になりました。
目次は、記事や固定ページのサイトマップをまとめた入口です。Googleはまずここを読みに来るので、ここが消えると、記事のサイトマップも見つけてもらえません。

原因は、目次が少し特別な扱いになっていたことです。「無いもの」と判定されてしまう作りだったので、目次だけを例外にして、すぐに直しました。

失敗その3:直したのに直っていないように見えた

もう1つ、確かめるときに迷ったことがあります。
直したはずなのに、ブラウザで開くとしばらく古い結果が出ていました。ConoHa WINGがページを一時的に保存して、速く返す仕組み(キャッシュ)を持っているからです。

直したあとに確かめるときは、アドレスの最後に ?test=1 のような、意味のない文字を付けて開くと、保存された古いページではなく、今の結果が見えます。

サイトマップ分のコード

さっきのファイルの下に、これを足しています。

// 4) サイトマップから「ユーザー」の1枚を外す
add_filter('wp_sitemaps_add_provider', function ($provider, $name) {
	if ('users' === $name) {
		return false;
	}
	return $provider;
}, 10, 2);

// 5) 無いサイトマップは、はっきり 404 を返す(トップページを出さない)
add_action('template_redirect', function () {
	$sitemap = sanitize_text_field((string) get_query_var('sitemap'));
	if ('' === $sitemap) {
		return;
	}
	// 目次(/wp-sitemap.xml)は特別扱い。ここを外すと目次ごと 404 になる
	if ('index' === $sitemap) {
		return;
	}
	if (function_exists('wp_sitemaps_get_server')) {
		$server = wp_sitemaps_get_server();
		if ($server && $server->registry->get_provider($sitemap)) {
			return;
		}
	}
	global $wp_query;
	$wp_query->set_404();
	status_header(404);
	nocache_headers();
	$template = get_404_template();
	if ($template) {
		include $template;
	}
	exit;
}, 1);

今日(2026年10月)あらためて、ログインしていない状態で確かめました。ユーザー一覧は「見つかりません」、?author=1 と著者ページはトップへ転送、ユーザーのサイトマップは「見つかりません」、サイトマップの目次はちゃんと開けます。


まだ残っている穴:ペンネームとログイン名が同じ

ここまで塞いでおいて何ですが、私のブログには、まだ穴が1つ残っています。

ペンネームとログイン名が同じ文字なんです。ブログを始めるときに、深く考えずに同じにしました。
ペンネームはサイドバーのプロフィールにも、運営者情報のページにも出しています。なので、私のログイン名は、5つの出口を塞いだ今でも、ブログを見れば分かります。

ログイン名は、WordPressではあとから変えられません。分けるには、別の名前で管理者を作り直して、記事をそちらに移す必要があるそうです。私はまだやっていないので、ここでは手順は書きません。
今のところは、前の章で書いたパスワードとログイン画面の守りのほうで受け止めている、というのが正直なところです。

これからWordPressを始める人は、最初からペンネームとログイン名を別の文字にしておくのをおすすめします。後から分けるより、ずっと楽です。


まとめ

  • 自分のブログに「投稿を編集」が出ていても、それはログインしている自分にしか見えていない。ログインしていないブラウザで開いて確かめる
  • ?author=1 と /wp-json/wp/v2/users を開けば、ログイン名が見えているかは誰でも確かめられる
  • WordPress公式は、ユーザー名を秘密の情報として扱っていない。本当の守りは、長いパスワードとログイン画面の守り
  • それでも気になるなら、mu-pluginsにファイルを1つ置けば塞げる。REST API全体は止めない
  • サイトマップにも出口がある。塞いだら、目次の /wp-sitemap.xml が開けるかまで確かめる
  • これから始める人は、ペンネームとログイン名を最初から別にしておく

私は専門家ではないので、これで完璧だとは思っていません。ただ、「えっ、みんなに見えてる?」と焦ったところから、自分で確かめて、自分で塞いで、残った穴まで分かっている、というところまでは来ました。同じところで焦っている人の、次の一歩になればうれしいです。