2026年9月16日
2026年9月16日
WordPressのパスワード強度ルールをカスタマイズする方法
WordPress標準のパスワード強度メーターは「弱い」と表示するだけで、弱いパスワードの保存自体は止めません。独自の強度ルールを実際に効かせるには、プロフィール更新とパスワードリセットのサーバー側処理で検証を加える必要があります。この記事では、標準の仕組みを確認したうえで、どんなルールにすべきか、mu-pluginでの実装方法、プラグインを使う場合の選択肢までを説明します。
標準のパスワード強度チェックの仕組み
WordPressのプロフィール画面やパスワードリセット画面には、入力中のパスワードを評価するメーターがあります。これはブラウザ上で動くJavaScript(zxcvbnという評価ライブラリ)による判定で、よくある単語や並び、ユーザー名との類似を見て「非常に弱い」から「強力」までを表示します。
弱いパスワードを入力すると「脆弱なパスワードの使用を確認」といった趣旨のチェックボックスが表示され、そこにチェックを入れれば保存できてしまいます。しかも判定はブラウザ側なので、JavaScriptを介さない送信には効きません。つまり標準の仕組みは「注意を促す」機能であり、ルールを強制したいならサーバー側での検証が必須です。
どんなルールにするか
「大文字・小文字・数字・記号を各1文字以上」のような文字種の組み合わせを強制するルールは、Password1! のような予測しやすいパスワードを生みがちです。米国NISTのデジタル認証ガイドライン(SP 800-63B)も、文字種の強制や定期的な変更の強制より、長さを重視し、漏えい済みやよく使われるパスワードを拒否する方向を示しています(2026年10月現在)。最新の推奨値は改訂で変わるため、採用前に原文を確認してください。
実務的には次のルールが扱いやすく、効果も高めです。
- 最低文字数:12文字以上など、十分な長さを求める
- よく使われるパスワードの拒否:
password、12345678、サイト名などを拒否する - ユーザー名・メールアドレスを含むものの拒否:推測の手がかりになるため
- 上限は緩く:長いパスフレーズを妨げないよう、極端に短い上限を設けない
パスワードの強さだけで守れる範囲には限界があるため、管理者アカウントには二要素認証、ログイン画面には試行回数の制限を併用するのが前提です。
mu-pluginでサーバー側の検証を追加する
検証が必要なのは主に次の2か所です。
- プロフィール画面と管理画面からのユーザー追加・編集:
user_profile_update_errorsアクション - wp-login.phpのパスワードリセット画面:
validate_password_resetアクション
どちらも WP_Error オブジェクトにエラーを追加すると保存が中止され、画面にメッセージが表示されます。作業前にバックアップを取り、ステージング環境で動作を確認してから本番に置いてください。
<?php
/**
* Plugin Name: Password Policy (Server-side)
* 置き場所: wp-content/mu-plugins/password-policy.php
*/
defined( 'ABSPATH' ) || exit;
/**
* パスワードがルールに合わない理由を配列で返す。合っていれば空配列。
* パスワードは比較にだけ使い、保存・ログ出力・画面表示はしない。
*/
function lsc_password_policy_errors( $password, $user_login = '', $user_email = '' ) {
$errors = array();
$lower = strtolower( $password );
if ( mb_strlen( $password ) < 12 ) {
$errors[] = 'パスワードは12文字以上にしてください。';
}
$common = array( 'password', 'passw0rd', '12345678', '123456789', 'qwertyuiop', 'wordpress', 'letmein' );
if ( in_array( $lower, $common, true ) ) {
$errors[] = 'よく使われるパスワードは使用できません。';
}
$needles = array( $user_login );
if ( $user_email && false !== strpos( $user_email, '@' ) ) {
$needles[] = strstr( $user_email, '@', true ); // メールアドレスの@より前
}
foreach ( $needles as $needle ) {
if ( strlen( $needle ) >= 3 && false !== stripos( $password, $needle ) ) {
$errors[] = 'ユーザー名やメールアドレスを含むパスワードは使用できません。';
break;
}
}
return $errors;
}
// プロフィール更新・ユーザー追加(管理画面)
add_action( 'user_profile_update_errors', function ( $errors, $update, $user ) {
if ( empty( $user->user_pass ) ) {
return; // パスワードを変更しない更新は対象外
}
$login = isset( $user->user_login ) ? $user->user_login : '';
if ( $update && ! empty( $user->ID ) ) {
$existing = get_userdata( $user->ID );
$login = $existing ? $existing->user_login : $login;
}
$email = isset( $user->user_email ) ? $user->user_email : '';
foreach ( lsc_password_policy_errors( $user->user_pass, $login, $email ) as $i => $message ) {
$errors->add( 'lsc_password_policy_' . $i, esc_html( $message ) );
}
}, 10, 3 );
// パスワードリセット画面(wp-login.php?action=rp)
add_action( 'validate_password_reset', function ( $errors, $user ) {
if ( ! ( $user instanceof WP_User ) || empty( $_POST['pass1'] ) ) {
return;
}
// パスワードは記号を含むためサニタイズで変形させない。比較にのみ使う。
$password = wp_unslash( $_POST['pass1'] );
foreach ( lsc_password_policy_errors( $password, $user->user_login, $user->user_email ) as $i => $message ) {
$errors->add( 'lsc_password_policy_' . $i, esc_html( $message ) );
}
}, 10, 2 );
コードのポイント
user_profile_update_errors に渡される $user は保存前のデータで、パスワードを入力したときだけ user_pass に値が入ります。空なら検証を飛ばすことで、パスワード以外の項目を更新するたびにエラーが出るのを防いでいます。既存ユーザーの更新ではユーザー名が渡されないことがあるため、get_userdata() で取り直しています。
validate_password_reset はリセット画面を開いたときにも呼ばれ、その時点では $user がエラーオブジェクトのこともあるため、WP_User かどうかを先に確認しています。パスワードに sanitize_text_field() をかけると記号や空白が変わり、ユーザーが入力したものと違う値で判定してしまうので、ここでは wp_unslash() だけにとどめ、比較以外には使いません。パスワードを error_log() などで記録するのは避けてください。
よく使われるパスワードの一覧は例として短くしています。実運用では、公開されている頻出パスワードのリストから上位数千件をファイルに置き、読み込んで照合する方法もあります。
画面のヒント文を合わせる
パスワード欄の下に表示される標準のヒント文は、password_hint フィルターで変更できます。ルールと説明が食い違うとユーザーが迷うため、サーバー側のルールに合わせて書き換えておきます。
add_filter( 'password_hint', function () {
return 'パスワードは12文字以上で、ユーザー名やメールアドレスを含まないものにしてください。長めの文章のようなパスフレーズもおすすめです。';
} );
このコードが効かない場面
WooCommerceのマイアカウントや会員プラグイン独自の登録・変更フォームは、標準とは別の処理でパスワードを保存していることがあり、上記のアクションを通らない場合があります。その場合は各プラグインが用意しているバリデーション用のフックを使うか、プラグイン側のパスワードルール設定を利用してください。また、WP-CLIや wp_set_password() を直接呼ぶ処理も検証の対象外です。
プラグインで設定する場合
コードを書かずに済ませたい、または有効期限や再利用禁止なども管理したい場合は、プラグインが選択肢になります(2026年10月現在)。
- Melapress Login Security / Password Policy Manager(Melapress):権限グループごとに文字数・文字種などのルールを設定できる
- Solid Security:パスワードの強度要件や、漏えい済みパスワードの拒否に関する機能を持つ
- Wordfence:ログイン保護の設定に強いパスワードを求める項目がある
製品名や機能の範囲はたびたび変わるため、導入前に公式ページで現在の機能を確認してください。セキュリティプラグイン同士は機能が重なりやすいので、パスワードルールを担当するのは1つに絞り、ここで紹介したmu-pluginと併用する場合はルールが矛盾しないようにします。
まとめ
- 標準の強度メーターは警告のみで、弱いパスワードの保存は止めない
- ルールは文字種の強制より、長さとよく使われるパスワード・ユーザー名の拒否を重視する
user_profile_update_errorsとvalidate_password_resetでサーバー側の検証を追加し、パスワードは比較以外に使わない- 独自フォームを持つプラグインは別途対応が必要で、二要素認証やログイン試行回数の制限と組み合わせて運用する