1

Does anyone know if you can override the default wordpress password strength expectations?

We just did a migration from an old system that has a different encryption. We will need to have all users reset their password. The current wordpress expectations are comically strict.

A client is very displeased about the necessity to have a password so strong nobody could ever crack it. They're not wrong. The site is pretty minimally exposed, and it is not a bank or anything. The users will definitely be dissuaded from this.

Searching common sense things bring up a sea of things like how to reset your password in wordpress. This is very clearly not what we need to know.

While we dig around to find something that can adjust this, I figured I might as well ask here in case there's a simple hook, or a plugin that bypasses this, or allows you to set your own rules to whatever degree.

I am not in control of this request. I cannot just tell the client to deal with it, so hopefully there is an answer that doesn't require me writing my own custom utility.

I should mention, we tried this plugin: https://plugins.miniorange.com/password-policy-manager

It looked like it had promise, but it seems the developer overlooked the reset password page itself. When I click forgot password, and then follow through with the email, it just takes me to the normal wp reset password page and has the default restrictions.

2 Answers 2

1

Ok so this has no convenient hook. I had to basically hijack the reset password page, and redirect it to my own implementation where I can be as foolish as I want with the rules.

function redirect_to_custom_password_reset() {
    if ( 'GET' == $_SERVER['REQUEST_METHOD'] ) {
        // Verify key / login combo 
        $user = check_password_reset_key( $_REQUEST['key'], $_REQUEST['login'] );
        if ( ! $user || is_wp_error( $user ) ) {
            //die($user->get_error_message());
            if ( $user && $user->get_error_code() === 'expired_key' ) {
                wp_redirect( home_url( 'member-login?login=expiredkey' ) );
            } else {
                wp_redirect( home_url( 'member-login?login=invalidkey' ) );
            }
            exit;
        }
        $redirect_url = get_permalink( 1234 ); //this is the ID of the page you make to handle this
        $redirect_url = add_query_arg( 'login', esc_attr( $_REQUEST['login'] ), $redirect_url );
        $redirect_url = add_query_arg( 'key', esc_attr( $_REQUEST['key'] ), $redirect_url );
        wp_redirect( $redirect_url );
        exit;
    }
}
add_action( 'login_form_rp', 'redirect_to_custom_password_reset' );
add_action( 'login_form_resetpass', 'redirect_to_custom_password_reset' );

You'll need a custom handler for updating the password. Something simple like this would do:

if(isset($_POST['rp_key']) && isset($_POST['rp_login'])){
    if($_POST['pass1'] == $_POST['pass2'] && strlen($_POST['pass1']) >= 10){
        $verify = check_password_reset_key($_POST['rp_key'], $_POST['rp_login']);

        if(!isset($verify->errors)){
            $update = wp_set_password($_POST['pass1'], $verify->ID);

            if($update){
                //do something, set a variable, or whatever
                $reset_pw_success = true;
            }
        }
    }else{
        $reset_pw_error = 'Invalid login keys';
    }
}

You'll need some code for the page you set up. You can make a page template, or a gutenberg block. Here's some sample code for what it might contain:

<?php
$verify = check_password_reset_key($_REQUEST['key'], $_REQUEST['login']);

global $reset_pw_error;
global $reset_pw_success;
$reset_error = false;

if(isset($reset_pw_error)){
    $reset_error = true;
}
?>
<section id="primary-content" class="section-default padded">
    <div class="shell">
        <div id="password-reset-form" class="widecolumn">
            <?php if(isset($reset_pw_success) && $reset_pw_success === true): ?>
                <h1>Success!</h1>
                <p>
                    Your password has been updated. You can now <a href="/login-registration/">login</a> with your new password.
                </p>
            <?php else: ?>
                <h1>Reset Your Password</h1>

                <?php if(!isset($verify->errors)): ?>
                <form name="resetpassform" id="resetpassform" action="" method="post" autocomplete="off">
                    <input type="hidden" id="user_login" name="rp_login" value="<?php echo esc_attr( $_GET['login'] ); ?>" autocomplete="off" />
                    <input type="hidden" name="rp_key" value="<?php echo esc_attr( $_GET['key'] ); ?>" />
                
                    <div class="form-row">
                        <label for="pass1">New Password</label>
                        <input type="password" name="pass1" id="pass1" class="input" size="20" value="" autocomplete="off" />
                    </div>
                    <div class="form-row">
                        <label for="pass2">Confirm New Password</label>
                        <input type="password" name="pass2" id="pass2" class="input" size="20" value="" />
                    </div>
                    
                    <p class="description">Your password needs to be at least 10 characters long. Use special characters if you want.</p>

                    <div id="reset-pw-message" <?php if($reset_error): ?>class="error"<?php endif; ?>><?php echo $reset_error ? $reset_pw_error : ''; ?></div>
                    
                    <p class="resetpass-submit">
                        <button type="submit" name="submit" id="resetpass-button">Reset Password</button>
                    </p>
                </form>
                <?php else: ?>
                <p>The password reset link has expired.</p>
                <?php endif; ?>

            <?php endif; ?>
        </div>
    </div>
</section>

And you'll probably want some basic JS validation:

$('#resetpass-button').click(function(e){
    var pw1 = $('#pass1').val();
    var pw2 = $('#pass2').val();
    error = [];

    if(pw1 == '' || pw2 == ''){
        error.push('Please make sure you enter a new password, and make it match the confirm password field.');
    }
    else
    {
        if(pw1.length < 10){
            error.push('Your new password has to be at least 10 characters long.');
        }

        if(pw1 !== pw2){
            error.push('Please make sure both password fields match exactly.');
        }
    }

    if(error.length > 0){
        e.preventDefault();
        $('#reset-pw-message').html(error.join('<br>')).slideDown().delay(8000).slideUp();
    }
});

This code is functional but you might want to try a little harder than I did. It was a quick patch for me, but I would consider making this a class and actually trying to protect things. Globals and procedural approaches tend to be frowned upon by many if they have to maintain the code after you.

2
  • Thanks for sharing. It's hard to believe one has to go this far to achieve something reasonable. Would love to see you put this in a plugin and maintain it ;-) Commented Sep 20 at 5:52
  • @SolaceBeforeDawn - LOL! I wouldn't want to maintain it. I'm way too lazy to add more to the already insane list of legacy favors I have to do out of kindness. I'm glad it is useful to someone though.
    – Kai Qing
    Commented Sep 20 at 19:55
0

See the answer here https://wordpress.stackexchange.com/a/356727/29416 , which states

Currently it's not possible to change the strength requirements of the password. You can only deactivate it the functionality completely by dequeueing the password script:

add_action( 'wp_print_scripts', 'DisableStrongPW', 100 );

function DisableStrongPW() {
    if ( wp_script_is( 'user-profile', 'enqueued' ) ) {
        wp_dequeue_script( 'user-profile' );
    }
}

For changing the minimum strength of the password I can recommend this plugin which builds on the same library and integrates nicely into woocommerce: https://wordpress.org/plugins/wc-password-strength-settings/

2
  • That disable PW hook is a common suggestion but when implemented, it didn't affect the reset password page at all. All it did was break the user edit panel, even for admins, by not allowing you to change the password at all. I ended up making a custom solution which I will paste as an answer when the site allows me to. You have to wait a couple days before answering your own question.
    – Kai Qing
    Commented Mar 15, 2023 at 18:40
  • Maybe digging into the core code for that script will give you some hints and possible filters. I just found that answer; haven't tested it. Answering your own question with a solution that works is very helpful here, though. Commented Mar 15, 2023 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.