WordPressの不正ログイン対策|二段階認証・パスキー・Googleログイン(OpenID Connect)で全アカウントを守る

目次

不正ログインはどこから起きるのか

WordPress本体より「古いプラグイン」と「弱いパスワード」が狙われる

「WordPressは脆弱だ」と言われがちですが、WordPress本体は頻繁にセキュリティ修正がリリースされており、更新さえしていれば極端に危険なソフトウェアではありません。実際の被害の多くは、次のような運用上の穴から起きています。

  • 更新されていないプラグイン・テーマの脆弱性
  • 推測しやすいパスワードや、他サービスで漏えいしたパスワードの使い回し
  • 使われなくなったまま放置されたアカウント

特にパスワードについては、総当たり攻撃(ブルートフォース)よりも、他サービスから流出したIDとパスワードの組み合わせを試す「リスト型攻撃」が主流です。どれだけ複雑なパスワードでも、使い回していれば意味がありません。

守るべきは管理者アカウントだけではない

不正ログイン対策というと管理者アカウントばかりに目が向きますが、ログインできるアカウントはすべて侵入口になり得ます。権限ごとに、乗っ取られた場合の被害を整理すると次のとおりです。

権限乗っ取られた場合にできること
管理者サイトの完全な掌握(プラグイン追加、ユーザー作成、不正コードの設置)
編集者全記事の改ざん、悪意あるリンクやスクリプトの埋め込み
投稿者自分の記事の改ざん、ファイルのアップロード
寄稿者下書きの作成程度(公開には承認が必要)
購読者ほぼ何もできない

記事やファイルを扱える投稿者以上の権限は、管理者と同じ強度で守るのが基本方針です。この記事で紹介する二段階認証やパスキーも、管理者だけでなく投稿者以上のすべてのアカウントに適用してください。

対策は1か所に頼るのではなく、サーバー・WordPress・認証の3つの層を重ねて考えると整理しやすくなります。それぞれの層でどんな対策が効くのかを図にまとめました。

不正ログインの試み サーバー層(レンタルサーバーの機能) WAF / 国外IPアクセス制限 / 管理画面のIPアドレス制限 WordPress層(運用と設定) 更新 / 不要なプラグイン・アカウント削除 / XML-RPC停止 認証層(ログインの仕組み) 二段階認証 / パスキー / OpenID Connect(Googleログイン) 管理画面(全ユーザー)

まず固めるべきWordPress側の土台

更新を止めない

WordPress本体・プラグイン・テーマは常に最新にしてください。管理画面の「プラグイン」一覧から、プラグインごとに自動更新を有効化できます。更新で表示が崩れるのが怖い場合でも、セキュリティ修正を放置するリスクのほうがはるかに大きいです。サーバーのPHPバージョンも、サポートが続いている新しいものを選びましょう。

長期間更新されていないプラグイン(最終更新が1〜2年以上前のもの)は、開発が止まっている可能性があります。脆弱性が見つかっても修正されないため、代替プラグインへの乗り換えを検討してください。

不要なプラグイン・テーマ・アカウントを削除する

使っていないプラグインやテーマは「停止」ではなく削除してください。停止していてもファイルはサーバー上に残っており、脆弱性があれば直接狙われることがあります。

アカウントも同様です。

  • 退職者や外注先など、もう使わないアカウントは削除する
  • 権限は必要最小限にする(記事を書くだけの人に管理者権限を渡さない)
  • 会員登録機能を使っていないなら、「設定 → 一般 → だれでもユーザー登録ができるようにする」をOFFにする

購読者アカウントは乗っ取られても被害は小さいものの、自由に作成できる状態は攻撃の足がかりやスパムの温床になります。

ユーザー名は「隠しきれない」前提で考える

ログイン名を「admin」やドメイン名にしないのは基本ですが、ユーザー名を完全に隠すのは実はかなり困難です。WordPressでは次のような経路からログイン名が推測できてしまいます。

  • https://example.com/?author=1 にアクセスすると、投稿者アーカイブ /author/ユーザー名/ にリダイレクトされる
  • REST APIの /wp-json/wp/v2/users でユーザーのスラッグが取得できる

プロフィールの「ブログ上の表示名」を変えても、このURLに使われるスラッグ(user_nicename)は初期状態でログイン名から作られるため変わりません。ユーザー名を隠す対策にこだわるより、ユーザー名が知られても突破されない認証を用意するほうが確実です。

XML-RPCを止める

XML-RPCは外部アプリからWordPressを操作するための古い仕組みで、1回のリクエストで大量のパスワードを試せるため総当たり攻撃によく使われます。Jetpackや一部の外部投稿アプリを使っていなければ、止めて問題ありません。

テーマの functions.php か、後述する専用プラグインファイルに次の1行を追加すると、認証が必要なXML-RPCの機能が無効になります。

add_filter( 'xmlrpc_enabled', '__return_false' );

多くのレンタルサーバーにはXML-RPCへのアクセスを制限する設定もあるため、サーバー側で止められるならそちらでも構いません。

レンタルサーバー側でできる対策

多くのレンタルサーバーには、WordPressを守るための機能がコントロールパネルに用意されています。プラグインを増やさずに使え、WordPressに届く前の段階で攻撃を弾けるのが利点です。名称はサーバー会社によって異なるので、以下を目安に自分のサーバーの管理画面を探してみてください。

機能内容名称の例
WAF不正なリクエストのパターンを検知して遮断するWAF設定、Webアプリケーションファイアウォール
国外IPアクセス制限海外からの管理画面・ログイン・XML-RPCへのアクセスを遮断する国外IPアクセス制限、海外アタックガード、国外IPアドレスフィルタ
ログイン試行回数制限短時間に何度もログインに失敗したアクセスを一時的に遮断するログイン試行回数制限
管理画面のIPアドレス制限登録したIPアドレス以外から管理画面に入れなくするダッシュボードアクセス制限、IPアドレス制限
自動バックアップサーバー側で定期的にデータを保存する自動バックアップ

国外IPアクセス制限は効果が大きい一方、海外出張中や海外のクラウドサービスから管理画面を操作する場合にも弾かれます。特定のIPアドレスだけ許可するホワイトリスト機能があるサーバーもあるので、必要に応じて使い分けてください。

IPアドレス制限は最強だが条件付き

管理画面にアクセスできるIPアドレスそのものを限定できれば、パスワードが漏れても攻撃者は管理画面にたどり着けません。ただし、自宅やオフィスの回線が固定IPでないと、IPアドレスが変わった瞬間に自分も締め出されます。複数人で運用していて全員の接続元を固定できる組織向けの対策です。固定IPがない個人の場合は、次の認証層の強化を優先してください。

認証方式を強くする

サーバーやWordPress側の対策は「攻撃を減らす」ものですが、最終的な守りは「誰が本人かをどう確かめるか」という認証の強さで決まります。主な選択肢を比較すると次のとおりです。

方式ログインの手間強さ向いているケース
パスワードのみ少ない弱い(漏えい・使い回しで突破される)単独では推奨しない
二段階認証(認証アプリ)毎回6桁のコード入力強いすべてのサイトの基本対策
パスキー指紋・顔認証のみ非常に強い(フィッシングにも強い)個人・少人数での運用
OpenID Connect(Googleログインなど)ボタンを押してGoogle等でログインGoogle等のアカウントの強さに依存Google WorkspaceやMicrosoft 365を使う組織

二段階認証(認証アプリ)

パスワードに加えて、スマホの認証アプリ(Google AuthenticatorやMicrosoft Authenticatorなど)が30秒ごとに表示する6桁のコードを入力させる方式です。パスワードが漏れても、スマホがなければログインできません。

WordPressでは「WP 2FA」や「Two Factor」などのプラグインで導入できます。導入時は次の点を確認してください。

  • 管理者だけでなく、投稿者以上の全権限で二段階認証を必須にする
  • スマホ紛失に備えて、表示されるバックアップコードを保管しておく
  • プラグインによっては「この端末を一定期間記憶する」機能があり、普段使うPCでの手間を減らせる

注意点として、偽のログインページにパスワードとコードを入力させてその場で中継する「リアルタイムフィッシング」には、認証アプリのコードでも対抗できません。この弱点を解消できるのが次のパスキーです。

パスキー

パスキーは、パスワードの代わりにスマホやPCに保存された暗号鍵で本人確認する仕組みです。ログイン時はFace ID、Touch ID、Windows Helloなどの生体認証を行うだけで、パスワードもコード入力も必要ありません。鍵は登録したサイトのドメインに結びついているため、偽サイトでは使えず、フィッシングにも強いのが特徴です。

WordPress本体には現時点で標準機能としては搭載されていないため、「Secure Passkeys」などのプラグインで追加します。権限ごとにパスキーの利用を許可・制限できるプラグインもあるので、投稿者以上に適用してください。

ここで見落とされがちな落とし穴があります。パスキーをプラグインで追加しただけでは、従来のユーザー名とパスワードによるログインもそのまま残ります。ログイン画面に入口が2つある状態になり、攻撃者は弱いほうのパスワードの入口を狙い続けられます。この状態と、パスワードログインを閉じた状態を比較したのが次の図です。

パスキーを追加しただけ パスキーでログイン 生体認証のみ・偽サイトで使えない パスワードでログイン 攻撃者はこちらを狙い続ける パスワードログインを閉じた後 パスキーでログイン 唯一の入口 パスワードでログイン 入口そのものがない

パスキーの効果を最大限に引き出すには、パスワードログインを閉じるか、少なくともパスワードを長くランダムなもの(パスワードマネージャーで生成・保管)にしておく必要があります。プラグインの設定にパスワードログインを無効化する項目があればそれを使い、なければ次の方法で閉じられます。

パスワードログインを閉じる

WordPressのパスワード認証は、authenticate フィルターに登録された関数で処理されています。これを外すと、ユーザー名・メールアドレスとパスワードの組み合わせではログインできなくなります。テーマを変更しても効果が消えないよう、wp-content/mu-plugins/ フォルダ(なければ作成)に次のファイルを置く方法がおすすめです。mu-pluginsに置いたファイルは自動的に有効化され、管理画面から停止することもできません。

<?php
/**
 * Plugin Name: Disable Password Login
 * Description: ユーザー名・メールアドレスとパスワードによるログインを無効化する
 */
add_action( 'init', function () {
	remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
	remove_filter( 'authenticate', 'wp_authenticate_email_password', 20 );
} );

導入時は必ず次の手順を守ってください。

  • 全員がパスキー(または後述のOpenID Connect)を登録し、それでログインできることを確認してから設置する
  • 設置後は、ログイン済みのブラウザを閉じずに、別のブラウザやシークレットウィンドウでパスキーログインが通るかを確認する
  • うまくいかなければ、サーバーのファイルマネージャーやFTPでこのファイルを削除すれば元に戻る

なお、パスキーやOpenID Connectのプラグインの実装によっては、このコードと干渉する可能性があります。本番サイトに入れる前に、テスト環境やステージング環境で動作を確認するのが安全です。

Googleログイン(OpenID Connect)で認証を任せる

OpenID Connect(OIDC)とは

OpenID Connect(OIDC)は、GoogleやMicrosoftなどの外部サービスに本人確認を任せ、その結果を受け取ってログインさせるための標準規格です。WordPressにGoogleアカウントやMicrosoftアカウントでログインする仕組みの多くは、このOIDCを使っています。本人確認を担当する側(GoogleやMicrosoft)を「IdP(アイデンティティプロバイダ)」と呼びます。

よく混同されるOAuth 2.0は、「他のサービスのデータにアクセスする許可(認可)」を受け渡すための仕組みです。OIDCはOAuth 2.0の上に「この人は誰か(認証)」を伝える仕組みを追加したもので、IdPは本人確認の結果を「IDトークン」という署名付きのデータで返します。WordPressはそのIDトークンを検証し、記載されたメールアドレスなどを手がかりにユーザーをログインさせます。

WordPressプラグインでよく使われる「認可コードフロー」の流れを図にすると次のようになります。

ブラウザ(利用者) WordPress Google / Microsoft ① ログインボタンを押す ② IdPのログイン画面へリダイレクト ③ パスキー等で本人確認 ④ 認可コードを持って戻る ⑤ コードをIDトークンと交換 (サーバー間の通信) ⑥ トークンを検証しログイン WordPressはパスワードを一切受け取らない

この仕組みの最大のメリットは、ログインの安全性をGoogleやMicrosoft側に任せられることです。Googleアカウントにパスキーや二段階認証を設定していれば、それがそのままWordPressの守りになります。WordPress側でパスワードを保管・照合する必要がなくなるため、パスワード漏えいのリスクそのものが減ります。

OpenID Connectが向いているケース

OIDCが本領を発揮するのは、組織でGoogle WorkspaceやMicrosoft 365(Entra ID)を使っているケースです。

  • 社員のログインを会社のアカウントで一元管理できる
  • 退職者のアカウントを会社側で停止すれば、自動的にWordPressにも入れなくなる
  • 二段階認証の強制などのポリシーを、IdP側でまとめて適用できる

一方、自分1人で運用する個人ブログであれば、設定の手間や設定ミスのリスクを考えると、パスキーのほうがシンプルです。なお、「Googleログイン」で検索すると訪問者向けの会員登録機能(ソーシャルログイン)の情報も多く出てきますが、ここで扱っているのはあくまでサイトの管理・編集をするユーザーのログインを守る目的での導入です。

OpenID Connect Generic Clientで設定する要点

GoogleやMicrosoftなど、さまざまなIdPに対応できる汎用プラグインが「OpenID Connect Generic Client」です。Googleログインに特化した、より設定が簡単なプラグインもありますが、ここでは仕組みを理解しやすい汎用プラグインでの要点を紹介します。

IdP側(Googleの場合)の準備

  • Google Cloudコンソールでプロジェクトを作成し、「Google Auth Platform」(旧「OAuth同意画面」)を設定する
  • Google Workspaceを使っているなら、対象ユーザーを「内部」にすると組織のアカウント以外はログインできなくなる
  • 個人のGoogleアカウントの場合は「外部」を選び、公開ステータスを「テスト」のままにしてテストユーザーに自分のアドレスだけを登録すると、登録したアカウント以外は認証そのものが通らない
  • 「クライアント」から種類「ウェブアプリケーション」でOAuthクライアントを作成し、承認済みのリダイレクトURIを登録する

このプラグインのリダイレクトURIは、初期設定では次の形式です(ドメインは自分のサイトに置き換えます)。

https://example.com/wp-admin/admin-ajax.php?action=openid-connect-authorize

WordPress側(プラグイン設定画面)

「設定 → OpenID Connect Client」で、IdPから発行されたクライアントIDとクライアントシークレットを入力し、各エンドポイントを設定します。主要なIdPの値は次のとおりです。

項目GoogleMicrosoft(Entra ID)
Login Endpoint URLhttps://accounts.google.com/o/oauth2/v2/authhttps://login.microsoftonline.com/{テナントID}/oauth2/v2.0/authorize
Token Validation Endpoint URLhttps://oauth2.googleapis.com/tokenhttps://login.microsoftonline.com/{テナントID}/oauth2/v2.0/token
Userinfo Endpoint URLhttps://openidconnect.googleapis.com/v1/userinfohttps://graph.microsoft.com/oidc/userinfo
OpenID Scopeopenid email profileopenid email profile

ユーザーを識別するIdentity Keyの初期値は preferred_username になっていることがありますが、Googleはこの値を返しません。Googleの場合は email または sub(IdP内で不変のユーザーID)を指定してください。

必ず確認すべき設定

OIDCの導入で最も危険なのは、IdPで認証が通った人を誰でもWordPressユーザーとして自動作成してしまう設定ミスです。このプラグインも、初期状態では未登録の人が認証に成功すると新規ユーザーを作成する動作になっています。外部向けのGoogleアカウントを許可した状態でこれが有効だと、Googleアカウントを持つ誰でもあなたのサイトにアカウントを作れてしまいます。

  • 未登録ユーザーを自動作成する設定(Create user if does not exist)をOFFにする
  • 既存のWordPressユーザーと紐づける設定(Link Existing Users)をONにし、WordPress側に登録済みのメールアドレスと一致する人だけがログインできるようにする
  • Microsoftの場合は、アプリ登録を「この組織のディレクトリのみ(シングルテナント)」にする。複数テナントを許可すると、他組織のユーザーが自分で設定したメールアドレスで成りすませる余地が生まれる
  • 動作確認が終わるまでは、ログイン方式を「ログインフォームにボタンを表示」にしておき、自動SSOにはしない

設定項目の名称はプラグインのバージョンによって変わる場合があるため、設定画面の説明もあわせて確認してください。

そして、パスキーと同じ落とし穴がここにもあります。OIDCを追加しても、WordPress標準のパスワードログインは残ったままです。OIDCでのログインを確認できたら、前述のmu-pluginsでパスワードログインを閉じることを検討してください。また、IdPのアカウントがすべての鍵になるため、GoogleやMicrosoftのアカウント側にはパスキーまたは二段階認証を必ず設定しておきましょう。

締め出されたときの復旧手段を用意しておく

認証を強くするほど、自分が締め出されたときの影響も大きくなります。対策を入れる前に、戻り方を確認しておいてください。

  • プラグインが原因の場合:サーバーのファイルマネージャーやFTPで wp-content/plugins/ 内の該当プラグインのフォルダ名を変更すると、そのプラグインが無効になり通常のログインに戻れる
  • パスワードログインを閉じた場合:wp-content/mu-plugins/ に置いたファイルを削除する
  • 端末の紛失に備える:パスキーはスマホとPCなど2台以上に登録し、二段階認証のバックアップコードは安全な場所に保管する
  • メールアドレスを守る:パスワードリセットはWordPressに登録したメールアドレス宛てに届くため、メールアカウントが乗っ取られるとWordPressも乗っ取られる。メール側にも二段階認証を設定する
  • レンタルサーバーのアカウントを守る:コントロールパネルに入られると、WordPressの認証に関係なくファイルを書き換えられてしまう。サーバー会社の会員アカウントにも二段階認証を設定する

ファイルマネージャーやFTPでの操作はサーバー側のアカウントで行うため、WordPressにログインできなくても実行できます。逆に言えば、サーバーのアカウントが最後の砦です。WordPressの認証を固めたら、その外側にある鍵の管理も忘れないようにしてください。

目次