Skip to navigation | Skip to content



Enforce strong WordPress passwords

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', __( 'ERROR: 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 on the 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!

4 comments

  1. Jerad (27th April 2010)

    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 (28th April 2010)

    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 (28th July 2010)

    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. Steve Taylor (28th July 2010)

    Thanks Gervásio, glad it’s of use!

Leave a comment

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

Want to show me some code? Don't paste long code here, link to a post at pastebin.ca or a similar site. Thanks.

Recent posts

Archives