Prevent Reusing Any of the Last 5 Passwords
Remembers the last five password hashes of each user and refuses a new password that matches one of them, on the profile screen and on password reset.
Opens WPIDE on
Code
// Number of previous passwords that cannot be reused.
$wpide_history_size = 5;
$wpide_is_reused = function ( $user_id, $password ) {
$user = get_userdata( $user_id );
if ( ! $user || '' === (string) $password ) {
return false;
}
$hashes = (array) get_user_meta( $user_id, 'wpide_password_history', true );
$hashes[] = $user->user_pass;
foreach ( array_filter( $hashes ) as $hash ) {
if ( wp_check_password( $password, $hash, $user_id ) ) {
return true;
}
}
return false;
};
$wpide_remember = function ( $user_id, $old_hash ) use ( $wpide_history_size ) {
$hashes = array_filter( (array) get_user_meta( $user_id, 'wpide_password_history', true ) );
$hashes[] = $old_hash;
update_user_meta( $user_id, 'wpide_password_history', array_slice( array_values( array_unique( $hashes ) ), -$wpide_history_size ) );
};
add_action( 'user_profile_update_errors', function ( $errors, $update, $user ) use ( $wpide_is_reused ) {
if ( $update && ! empty( $user->user_pass ) && ! empty( $user->ID ) && $wpide_is_reused( $user->ID, $user->user_pass ) ) {
$errors->add( 'wpide_password_reused', '<strong>Error:</strong> Please choose a password you have not used recently.' );
}
}, 10, 3 );
add_action( 'validate_password_reset', function ( $errors, $user ) use ( $wpide_is_reused ) {
$pass = isset( $_POST['pass1'] ) ? (string) wp_unslash( $_POST['pass1'] ) : '';
if ( $pass && $user instanceof WP_User && $wpide_is_reused( $user->ID, $pass ) ) {
$errors->add( 'wpide_password_reused', 'Please choose a password you have not used recently.' );
}
}, 10, 2 );
add_action( 'profile_update', function ( $user_id, $old_data ) use ( $wpide_remember ) {
$user = get_userdata( $user_id );
if ( $user && $old_data && $old_data->user_pass && $user->user_pass !== $old_data->user_pass ) {
$wpide_remember( $user_id, $old_data->user_pass );
}
}, 10, 2 );
add_action( 'password_reset', function ( $user ) use ( $wpide_remember ) {
$wpide_remember( $user->ID, $user->user_pass );
} );
Notes
Only hashes are stored, never the passwords themselves; history starts building from the next password change.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.