Type something to search...
How to force strong passwords for WordPress users?

How to force strong passwords for WordPress users?

WordPress suggests strong passwords but doesn't enforce them, because any user can tick the "Confirm use of weak password" checkbox and save something like password123. To force strong passwords, you can enable the password requirements feature in a security plugin such as Solid Security, Wordfence, or Melapress Login Security, or add a small custom plugin that validates passwords with the user_profile_update_errors and validate_password_reset hooks before WordPress saves them.

Weak and reused passwords remain one of the easiest ways into a WordPress site, and a single editor with a poor password can put the whole site at risk. This article explains how WordPress handles passwords by default, what a sensible password policy looks like in 2026, how to enforce one with plugins, and how to build your own enforcement with code, including a check against known breached passwords.

How WordPress Handles Passwords by Default

When you create a user or change a password in WordPress, the password field comes with a built-in strength meter powered by the zxcvbn library. It rates passwords as Very weak, Weak, Medium, or Strong, and WordPress generates a strong random password by default when you click Set New Password or add a new user.

However, the meter is advisory. If a user types a weak password, WordPress shows a checkbox labelled Confirm use of weak password. Once ticked, the password is accepted. There is no minimum length, no requirement for variety, and no check against leaked passwords.

WordPress does handle storage well. Passwords are hashed rather than stored in plain text, and WordPress 6.8 moved core to bcrypt hashing, which makes stolen password hashes much harder to crack. But secure storage doesn't help if the password itself is easy to guess.

Why Forcing Strong Passwords Matters

Attackers rarely guess passwords by hand. They use automated tools that try common passwords, dictionary words, and credentials leaked from other breaches. Enforcing strong passwords helps in several ways:

  • It defeats dictionary and brute-force attacks: Long, unique passwords can't be guessed within any realistic number of attempts.
  • It blocks credential stuffing: Rejecting passwords that appear in known breaches stops users from reusing a password that attackers already have.
  • It protects every role, not just admins: An editor or shop manager account can still publish malicious content or leak customer data.
  • It supports compliance: Many security standards and privacy frameworks expect reasonable access controls, and a password policy is part of that.

What Makes a Strong Password Policy in 2026?

Password advice has changed over the years. Modern guidance, including NIST's digital identity guidelines, favours length and breach checks over complex composition rules. Forcing users to include a symbol and a number often produces predictable passwords like Summer2026!, while a long passphrase is both easier to remember and harder to crack.

A practical policy for most WordPress sites looks like this:

  1. Minimum length: At least 12 characters for regular users, and consider 14 to 16 or more for administrators.

  2. No breached passwords: Reject any password that appears in a known data breach list.

  3. No obvious personal information: Don't allow the username, email address, or site name as part of the password.

  4. Strength meter score: Require a "Strong" result from the built-in meter if your plugin supports it.

  5. Allow long passphrases and paste: Let users paste passwords from a password manager, and don't cap the maximum length at something small.

  6. Avoid forced periodic resets: Requiring changes every 30 or 90 days tends to create weaker passwords. Force a reset when there's evidence of compromise instead.

Enforcing strong passwords works best together with two-factor authentication, especially for administrators.

Method 1: Force Strong Passwords With a Plugin

Plugins are the fastest route and usually include extra features such as policies per role and forced resets.

Solid Security

Solid Security (formerly iThemes Security) includes password requirements in its user security settings.

  1. Install and activate: Go to Plugins > Add New Plugin, search for "Solid Security", then install and activate it.

  2. Open the settings: Navigate to Security > Settings and look for the password requirements options, which in recent versions sit with the login security features and can be applied per user group.

  3. Enable strong passwords: Turn on the requirement for strong passwords and choose which user groups it applies to, such as administrators and editors.

  4. Refuse compromised passwords: Enable the option to reject passwords found in known breaches. This uses a privacy-preserving lookup against the Have I Been Pwned database.

  5. Save and test: Save your changes, then try setting a weak password on a test account to confirm it's blocked.

Menu names can shift between versions, so if you don't see these exact labels, look for "Password Requirements" in the plugin's settings.

Wordfence

Wordfence includes an option to enforce strong passwords. Go to Wordfence > All Options, expand Brute Force Protection, and set Enforce strong passwords to apply to admins and publishers or to all users. Wordfence can also prevent the use of passwords leaked in data breaches for users with publishing capabilities.

Melapress Login Security

Melapress Login Security (previously known as WPassword) focuses specifically on password and login policies. It lets you set minimum length, character requirements, password history so users can't reuse old passwords, password expiration, and different policies per user role. This is a good choice if you need granular, role-based rules for a membership or company site.

WooCommerce Sites

WooCommerce uses its own strength meter on the My Account and checkout pages. By default it requires a medium-strength password. You can raise this with the woocommerce_min_password_strength filter, where 0 is very weak and 4 is strong:

add_filter( 'woocommerce_min_password_strength', function () {
return 4;
} );

Note that this only affects WooCommerce's front-end forms. Use one of the methods above or below to cover the WordPress admin and login screens.

Method 2: Force Strong Passwords With Custom Code

If you prefer not to install a full security plugin, you can enforce a policy with a small custom plugin. This approach validates passwords on the server, so it can't be bypassed by ticking a checkbox or disabling JavaScript.

Before adding code, back up your site. Then create a folder at wp-content/plugins/sajjad-password-policy/ and add a file called sajjad-password-policy.php.

The Password Policy Plugin

<?php
/**
 * Plugin Name: Sajjad Password Policy
 * Description: Enforces minimum length, blocks personal info, and rejects breached passwords.
 * Version:     1.0.0
 * Author:      Sajjad
 */

defined( 'ABSPATH' ) || exit;

define( 'SAJJAD_PP_MIN_LENGTH', 12 );

/**
 * Check a password against the Have I Been Pwned range API.
 *
 * Only the first five characters of the SHA-1 hash are sent,
 * so the actual password never leaves your server.
 *
 * @return bool True if the password appears in a known breach.
 */
function sajjad_pp_is_pwned( $password ) {
$hash   = strtoupper( sha1( $password ) );
$prefix = substr( $hash, 0, 5 );
$suffix = substr( $hash, 5 );

$response = wp_remote_get(
'https://api.pwnedpasswords.com/range/' . $prefix,
array(
'timeout' => 5,
'headers' => array( 'Add-Padding' => 'true' ),
)
);

// Fail open if the service is unreachable, so users aren't blocked.
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return false;
}

$lines = preg_split( '/\r\n|\r|\n/', wp_remote_retrieve_body( $response ) );

foreach ( $lines as $line ) {
$parts = explode( ':', trim( $line ) );

if ( 2 === count( $parts ) && $parts[0] === $suffix && (int) $parts[1] > 0 ) {
return true;
}
}

return false;
}

/**
 * Validate a password against the policy.
 *
 * @param string   $password The plain-text password.
 * @param WP_Error $errors   Error object to add messages to.
 * @param string   $login    The user's login name.
 * @param string   $email    The user's email address.
 */
function sajjad_pp_validate( $password, $errors, $login = '', $email = '' ) {
if ( mb_strlen( $password ) < SAJJAD_PP_MIN_LENGTH ) {
$errors->add(
'sajjad_pp_length',
sprintf(
/* translators: %d: minimum number of characters. */
esc_html__( 'Your password must be at least %d characters long.', 'sajjad-password-policy' ),
SAJJAD_PP_MIN_LENGTH
)
);
return;
}

$lower_password = mb_strtolower( $password );
$email_name     = $email ? strstr( $email, '@', true ) : '';

foreach ( array( $login, $email_name ) as $personal ) {
if ( $personal && mb_strlen( $personal ) >= 3 && false !== strpos( $lower_password, mb_strtolower( $personal ) ) ) {
$errors->add(
'sajjad_pp_personal',
esc_html__( 'Your password must not contain your username or email address.', 'sajjad-password-policy' )
);
return;
}
}

if ( sajjad_pp_is_pwned( $password ) ) {
$errors->add(
'sajjad_pp_pwned',
esc_html__( 'This password has appeared in a known data breach. Please choose a different one.', 'sajjad-password-policy' )
);
}
}

/**
 * Enforce the policy when adding users or editing profiles in wp-admin.
 */
function sajjad_pp_profile_errors( $errors, $update, $user ) {
if ( empty( $user->user_pass ) ) {
return; // Password not being changed.
}

$login = '';
if ( ! empty( $user->user_login ) ) {
$login = $user->user_login;
} elseif ( ! empty( $user->ID ) ) {
$existing = get_userdata( $user->ID );
$login    = $existing ? $existing->user_login : '';
}

$email = ! empty( $user->user_email ) ? $user->user_email : '';

sajjad_pp_validate( $user->user_pass, $errors, $login, $email );
}
add_action( 'user_profile_update_errors', 'sajjad_pp_profile_errors', 10, 3 );

/**
 * Enforce the policy on the "Reset Password" screen.
 */
function sajjad_pp_reset_errors( $errors, $user ) {
if ( ! isset( $_POST['pass1'] ) || ! $user instanceof WP_User ) {
return;
}

// Don't sanitize passwords: it would change the value. It is never output.
$password = wp_unslash( $_POST['pass1'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput, WordPress.Security.NonceVerification

if ( '' === $password ) {
return;
}

sajjad_pp_validate( $password, $errors, $user->user_login, $user->user_email );
}
add_action( 'validate_password_reset', 'sajjad_pp_reset_errors', 10, 2 );

/**
 * Hide the "Confirm use of weak password" checkbox.
 */
function sajjad_pp_hide_weak_checkbox() {
echo '<style>.pw-weak { display: none !important; }</style>';
}
add_action( 'admin_head', 'sajjad_pp_hide_weak_checkbox' );
add_action( 'login_head', 'sajjad_pp_hide_weak_checkbox' );

Activate it under Plugins > Installed Plugins.

How the Code Works

  1. Length check: Passwords shorter than the minimum are rejected immediately with a clear message. Change SAJJAD_PP_MIN_LENGTH to suit your policy.

  2. Personal information check: The password can't contain the user's login or the part of their email before the @ sign.

  3. Breach check: The plugin hashes the password with SHA-1 and sends only the first five characters of that hash to the Have I Been Pwned range API. The API returns a list of matching hash suffixes, and the comparison happens on your server. The actual password is never sent anywhere. The Add-Padding header adds fake entries to the response for extra privacy, which is why the code only counts matches with a count above zero.

  4. Profile and new-user screens: The user_profile_update_errors hook runs when an administrator adds a user under Users > Add New User or when anyone saves a profile under Users > Profile. Adding an error stops the save.

  5. Password reset screen: The validate_password_reset hook covers the "Reset Password" form users reach from the "Lost your password?" link. WordPress core handles the reset key verification for that form.

  6. Hiding the weak password checkbox: The CSS hides the checkbox so users aren't confused, but the real enforcement is the server-side validation. Even if someone reveals the checkbox, their weak password is still rejected.

A Note on Fail-Open Behaviour

The breach check intentionally "fails open": if the API can't be reached, the password is still judged by length and personal information rules instead of blocking the user entirely. If you need a strict policy, you could fail closed instead, but that means users can't change passwords during an outage. For most sites, failing open is the more practical choice.

Where the Code Doesn't Reach

WordPress core covers the admin profile screens and the password reset form. Some plugins provide their own front-end registration, account, or profile forms, such as membership plugins, WooCommerce, or form builders. Those forms may save passwords through their own code paths. Check each plugin's documentation for its password strength settings or hooks, and test every form where users can set a password.

Forcing Existing Users to Update Weak Passwords

A new policy only applies when a password is set or changed, so existing weak passwords remain in place. You can't check existing passwords directly, because WordPress only stores hashes. Instead, you can ask users to set new passwords.

Send Password Reset Emails

In the dashboard, go to Users > All Users, select the users you want to reset, and choose Send password reset from the Bulk actions menu. Each user receives an email with a link to set a new password, which will be validated by your new policy.

Reset Passwords With WP-CLI

For larger sites, WP-CLI is faster. The wp user reset-password command resets passwords and emails users a reset link:

# Reset passwords for all administrators and editors, and email them.
wp user reset-password $(wp user list --role=administrator --field=user_login)
wp user reset-password $(wp user list --role=editor --field=user_login)

Resetting a password invalidates the old password immediately, so warn your team before doing this. Add the --skip-email flag only if you plan to notify users another way.

Best Practices for Password Security

Enforcing strong passwords works best as part of a wider approach:

  • Encourage password managers: Tools like Bitwarden, 1Password, or your browser's built-in manager make long, unique passwords effortless.
  • Use WordPress's generated passwords: The Generate Password button produces a strong random password that's ideal with a password manager.
  • Add two-factor authentication: Especially for administrators, a second factor protects the account even if a password leaks.
  • Limit login attempts: A lockout policy stops bots from making endless guesses.
  • Review user accounts regularly: Remove accounts that are no longer needed and downgrade roles where possible.
  • Use application passwords for integrations: Instead of sharing a real password with a third-party service, create an application password under Users > Profile > Application Passwords and revoke it when no longer needed.

FAQ: Forcing Strong Passwords in WordPress

No. WordPress shows a strength meter and suggests a strong password, but users can tick the Confirm use of weak password checkbox and save any password they like.

At least 12 characters is a sensible baseline for regular users. Administrators should use longer passwords or passphrases, ideally generated by a password manager, combined with two-factor authentication.

Yes, when you use the range API. Only the first five characters of the password's SHA-1 hash are sent, and the full comparison happens on your server, so the password itself never leaves your site.

Yes. Plugins such as Melapress Login Security and Solid Security let you apply policies per role or user group. With custom code, you can check the user's role inside your validation function and adjust the rules.

Modern guidance generally advises against routine forced changes, because they lead to predictable passwords. Require a change when there is a sign of compromise, such as a breach or suspicious login activity.

Only when they next change their password. To bring existing accounts in line, send password reset emails from Users > All Users or use the WP-CLI user reset-password command.

Not on its own. Hiding it with CSS only improves the interface. Real enforcement must happen on the server with validation hooks or a security plugin.


Conclusion

WordPress gives users good tools for choosing strong passwords, but it leaves the final decision to them. Forcing strong passwords closes that gap. A security plugin like Solid Security, Wordfence, or Melapress Login Security can enforce a policy in a few clicks, while a small custom plugin using user_profile_update_errors and validate_password_reset gives you precise control, including a privacy-friendly breach check.

Focus your policy on length and rejecting breached passwords rather than complicated character rules, extend it to any front-end forms your plugins provide, and ask existing users to reset their passwords once the policy is live. Combined with two-factor authentication and limited login attempts, a strong password policy makes account takeover one of the least likely ways your site will be compromised.

Share :

Related Posts

What are the best WordPress security plugins?

What are the best WordPress security plugins?

The best WordPress security plugins for most sites are Wordfence, Sucuri Security, Solid Security, MalCare, All-In-One Security (AIOS), Patchstack, a

Dive Deeper
What are the most common website security threats?

What are the most common website security threats?

The most common website security threats are vulnerable or outdated software, weak and stolen passwords, malware infections, injection attacks like S

Dive Deeper
What is the difference between posts and pages in WordPress?

What is the difference between posts and pages in WordPress?

The main difference between posts and pages in WordPress is that posts are timely, dated entries that appear in your blog feed, archives, and RSS fee

Dive Deeper