Steve Taylor photo

Enforce strong WordPress passwords

UPDATE: You can now get this code as a plugin.

Here we go with some more nifty code for you WordPress developers… As ever, this code is roughly tested but probably not for novices. It’s designed to drop into a custom theme’s functions.php file. It probably should be a plugin, and it might make it one day when it’s thoroughly tested and I get time…

Anyway, it’s a solution to a problem that I’m very surprised isn’t built into the WP core (as an option at least), and isn’t addressed by any easily found plugin or code already out there. As we know, WP provides a good “password strength meter” on the user profile page, which is great as strong passwords are (or should be) one of the first lines of defence against attacks on your site. But it’s just an indicator—there’s nothing stopping someone using “password” as their password, or something dumb like that. All you need is one Administrator or Editor with a dumb password, and the whole site is highly vulnerable.

How about a little enforcement?

The code below basically replicates the WP core password meter check, translated from JavaScript to PHP, and uses it to validate passwords that are entered.

// Enforce strong passwords
function slt_strongPasswords( $errors ) {
	$enforce = true;
	$args = func_get_args();
	$userID = $args[2]->ID;
	if ( $userID ) {
		// User ID specified - omit check for user levels below 5
		$userInfo = get_userdata( $userID );
		if ( $userInfo->user_level < 5 ) {
			$enforce = false;
		}
	} else {
		// No ID yet, adding new user - omit check for "weaker" roles
		if ( in_array( $_POST["role"], array( "subscriber", "author", "contributor" ) ) ) {
			$enforce = false;
		}
	}
	if ( $enforce && !$errors->get_error_data("pass") && $_POST["pass1"] && slt_passwordStrength( $_POST["pass1"], $_POST["user_login"] ) != 4 ) {
			$errors->add( 'pass', __( '<strong>ERROR</strong>: Please make the password a strong one.' ) );
	}
	return $errors;
}
add_action( 'user_profile_update_errors', 'slt_strongPasswords', 0, 3 );

// Check for password strength
// Copied from JS function in WP core: /wp-admin/js/password-strength-meter.js
function slt_passwordStrength( $i, $f ) {
	$h = 1; $e = 2; $b = 3; $a = 4; $d = 0; $g = null; $c = null;
	if ( strlen( $i ) < 4 )
		return $h;
	if ( strtolower( $i ) == strtolower( $f ) )
		return $e;
	if ( preg_match( "/[0-9]/", $i ) )
		$d += 10;
	if ( preg_match( "/[a-z]/", $i ) )
		$d += 26;
	if ( preg_match( "/[A-Z]/", $i ) )
		$d += 26;
	if ( preg_match( "/[^a-zA-Z0-9]/", $i ) )
		$d += 31;
	$g = log( pow( $d, strlen( $i ) ) );
	$c = $g / log( 2 );
	if ( $c < 40 )
		return $e;
	if ( $c < 56 )
		return $b;
	return $a;
}

A few notes:

  • Initially, in slt_strongPasswords(), which is hooked to the user_profile_update_errors action, we check whether we’re editing or creating a user here. This enables a check on the user level / role. Here, I’m only enforcing the strong password for “executive” users, i.e. those whose role lets them significantly affect the site. I’m taking this to be Editors (or, in the old style, Level 5) and above. I’m well aware that roles and capabilities in WP, and possible modifications of that system, mean that this may not be a one-size-fits-all solution. Obviously, adapt as necessary for your system—and do chip in here with any suggestions for better / different checks. If you want to enforce strong passwords for all users, just delete or comment out lines 4-17.
  • I’ve translated the WP core JavaScript function that runs the password strength meter here into PHP. If you root around in the core source (/wp-admin/js/user-profile.dev.js, you’ll see that the value 4 is returned for “strong” passwords. Here, where there is enforcement, I’m limiting allowed passwords to “strong” only. Again, tweak this if you want to—perhaps different strengths enforced for different user roles.
  • One slight hole I know is here is if someone changes a user’s password at the same time as changing their role from something like Subscriber to Administrator. A weak password would get through this. Also, an account with a weak password could just be changed to an Administrator, and if no new password is entered, again, the check wouldn’t be triggered. I’m assuming that people editing other’s accounts will be trusted and know what they’re doing. But still, it’s an area where this code could definitely be improved—certainly it’d be necessary before making this a plugin.

Let me know if this is useful and if you find any bugs or suggestions for improvement!

11 comments

  1. Jerad avatar Jerad

    I know this is a total noob question, but I would like to use this code but need to find out where to put it. Thanks for your time.

  2. Steve Taylor avatar Steve Taylor

    As mentioned in the first para, it goes into the functions.php file of a theme. Check the docs on this if you’re not sure.

  3. Gervásio avatar Gervásio

    I’ve implemented this in a website I’m putting on. It’s working great so far. Big thanks!

    It’s odd nobody has created a plugin with this functionality yet :(

  4. thank you, steve taylor :-)
    i just did create the plugin for my multisite, its quite trivial :-) but have no time… i’ll upload it on wordpress.org only on request

  5. Mak avatar Mak

    i have implement in website but it does not work can u tell why it happen?
    i have put it in function.php and then create a user with weak password but it allow me to create new user.

  6. Hi Mak, my guess is you’re putting the code into /wp-includes/functions.php (a core file which should never be altered) instead of into /wp-content/themes/[your custom theme which is activated]/functions.php. If you’ve got the code in the right file, I’m not sure I can help I’m afraid. Maybe contact zaantar (previous comment to you) for his plugin?

  7. Abhik Sarkar avatar Abhik Sarkar

    Hi Steve,

    I was wondering if you were planning on creating a plugin for this (as I understand nothing of complicated codes) :(

    Also, while the password I create for my admin login on my various blogs is usually a strong one…what happens if I have a membership site using wordpress? What happens if a subscriber creates a weak password on their (user level access)…does my members weak password threaten the security of my blog from an admin point of view?

    Thanks,

    Abhik

  8. Hi Abhik, I’m not planning on releasing a plugin of this. However, plugins are incredibly easy to create.

    I think the danger posed by weak passwords depends on the role assigned to the user. If an Author has their WP login hacked, it’s less of a problem than if an Editor is hacked.

  9. Mary avatar Mary

    Hi Steve,

    Just wanted to let you know that the code you provided on this article is working great!

    Thanks for your awesome work :)

  10. juries avatar juries

    Really great code you provided for us Steve..and its working very well. Thank you much!

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>