Test a bunch of permutations of the password when logging into WordPress.
<?php | |
/** | |
* Test a bunch of permutations of the password when logging into WordPress. | |
* | |
* Drop this file in your mu-plugins directory. | |
* Inspired by Facebook: https://twitter.com/gcpascutto/status/821755332984717314/photo/1 | |
* Works with any properly coded hashing pluggables, like Roots’ WP Password bcrypt. | |
* | |
* @author bjornjohansen | |
* @version 0.1.4 | |
* @license https://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU General Public License version 2 (GPLv2) | |
* @package Test_Password_Permutations | |
*/ | |
add_filter( 'check_password', 'test_password_permutations', 20, 4 ); | |
/** | |
* Try permutations of the password if the login failed. | |
* | |
* @param bool $check Whether the passwords match. | |
* @param string $password The plaintext password. | |
* @param string $hash The hashed password. | |
* @param string|int $user_id User ID. Can be empty. | |
* @return bool False, if none of the $password permutations match the hashed password. | |
*/ | |
function test_password_permutations( $check, $password, $hash, $user_id ) { | |
// Don’t run this filter recursively (it is applied in wp_check_password() ). | |
if ( ! apply_filters( 'enable_password_fixer_filter', true ) ) { | |
return $check; | |
} | |
if ( ! has_filter( 'enable_password_fixer_filter' ) ) { | |
add_filter( 'enable_password_fixer_filter', '__return_false' ); | |
} | |
if ( $check ) { | |
// Password was correct. No need for us to try permutations. | |
return $check; | |
} | |
// Accept password if a user inadverntently has caps lock enabled. | |
if ( ! $check ) { | |
// Flip case. | |
$test_password = ''; | |
for ( $i = 0, $c = mb_strlen( $password ); $i < $c; $i++ ) { | |
$char = mb_substr( $password, $i, 1 ); | |
if ( mb_strtoupper( $char ) === $char ) { | |
$test_password .= mb_strtolower( $char ); | |
} else { | |
$test_password .= mb_strtoupper( $char ); | |
} | |
} | |
$check = wp_check_password( $test_password, $hash ); | |
} | |
// Accept password if their mobile device automatically capitalized the first character of the password. | |
if ( ! $check ) { | |
$test_password = mb_strtolower( mb_substr( $password, 0, 1 ) ) . mb_substr( $password, 1 ); | |
// Only test if the permutation actually changed the password. | |
if ( $test_password !== $password ) { | |
$check = wp_check_password( $test_password, $hash ); | |
} | |
} | |
// Accept password if an extra character is added to the end of the password. | |
if ( ! $check ) { | |
$test_password = mb_substr( $password, 0, mb_strlen( $password ) -1 ); | |
// Only test if the permutation actually changed the password. | |
if ( $test_password !== $password ) { | |
$check = wp_check_password( $test_password, $hash ); | |
} | |
} | |
// Trim whitespaces from both ends of the password. | |
if ( ! $check ) { | |
$test_password = trim( $password ); | |
// Only test if the permutation actually changed the password. | |
if ( $test_password !== $password ) { | |
$check = wp_check_password( $test_password, $hash ); | |
} | |
} | |
return $check; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
I have written a post on the subject that explains this more, and with some password security math: https://bjornjohansen.no/wordpress-assisted-password-check