Tuesday, 6 June 2023

WordPress and "Confirm use of weak password"

 I don't want people to use weak passwords on my WordPress site, I looked for PHP code to disable the "Confirm use of weak password" row and checkbox but couldn't find anything that worked.  

My environment is WordPress 6.2.2 with a child OceanWP theme.

It seemed easiest to simply use CSS to disable it.  Obviously the CSS needs to be enqueued with PHP (for admin):


add_action( 'admin_head', 'BungalookAdministrationHeaderAssets');

 The CSS itself follows (include it in the enqueued CSS file):


.pw-weak { display: none !important; }

To improve the password requirements you can have a look at "Enforce Strong Passwords Without a Plugin - WordPress Tutorial", this is good but perhaps a bit confusing as you must first pass WordPress's "weak" check before the password can be submitted for further validation by the extra code.

Any error message is displayed at the top of the window (which may not be visible) and WordPress doesn't always scroll there...

I have modified the code a bit to display more informative error messages such as this one:


The complete modified PHP code follows:


/**
 * Enforce strong passwords (ESP) for all website users.
 *
 * https://wp-tutorials.tech/optimise-wordpress/enforce-strong-passwords-without-a-plugin/
 *
 * To disable enforcing strong passwords:
 *   define('ESP_IS_ENABLED', false);
 */

defined('WPINC') || die();

/**
 * Initialise constants and handlers.
 */
//===========================================================================
function esp_init()
//===========================================================================
{
   if (defined('ESP_IS_ENABLED') && (ESP_IS_ENABLED === false)) {
      // Disabled by configuration.
   } else {
      add_action('user_profile_update_errors',  'esp_user_profile_update_errors', 0, 3);
      add_action('resetpass_form',              'esp_resetpass_form', 10);
      add_action('validate_password_reset',     'esp_validate_password_reset', 10, 2);
   }
}
add_action('init', 'esp_init');



//===========================================================================
function esp_user_profile_update_errors($errors, $update, $user_data)
//===========================================================================
{
   return esp_validate_password_reset($errors, $user_data);
}

//===========================================================================
function esp_resetpass_form($user_data)
//===========================================================================
{
   return esp_validate_password_reset(false, $user_data);
}

//===========================================================================
/**
 * Sanitise the input parameters and then check the password strength.
 */
function esp_validate_password_reset($errors, $user_data)
//===========================================================================
{
   $is_password_ok = false;

   $user_name = null;
   if (isset($_POST['user_login'])) {
      $user_name = sanitize_text_field($_POST['user_login']);
   } elseif (isset($user_data->user_login)) {
      $user_name = $user_data->user_login;
   } else {
      // No user specified.
   }

   $password = null;
   if (isset($_POST['pass1']) && !empty(trim($_POST['pass1']))) {
      $password = sanitize_text_field(trim($_POST['pass1']));
   }

   $error_message = null;
   if (is_null($password)) {
      // Don't do anything if there isn't a password to check.
   } elseif (is_wp_error($errors) && $errors->get_error_data('pass')) {
      // We've already got a password-related error.
   } elseif (empty($user_name)) {
      $error_message = __('User name cannot be empty.');
   } else
   {
      $error_message = esp_is_password_ok($password, $user_name);
   }

   if (!empty($error_message))
   {
      //--- Display error message -------------------------------------------
      $error_message = 'ERROR: ' . $error_message;
      if (!is_a($errors, 'WP_Error')) {
         $errors = new WP_Error('pass', $error_message);
      } else {
         $errors->add('pass', $error_message);
      }
   }

   return $errors;
}

//===========================================================================
/**
 * Given a password, return "" if it's OK, otherwise return Reason it isn't.
 */
function esp_is_password_ok($password, $user_name)
//===========================================================================
{
    //--- Get userid & Password ---------------------------------------------
    $password = sanitize_text_field($password);
    $user_name = sanitize_text_field($user_name);

    //--- Run some checks ---------------------------------------------------
    $is_number_found    = preg_match('/[0-9]/',          $password);
    $is_lowercase_found = preg_match('/[a-z]/',          $password);
    $is_uppercase_found = preg_match('/[A-Z]/',          $password);
    $is_symbol_found    = preg_match('/[^a-zA-Z0-9]/',   $password);

    //--- Passed the above checks? ------------------------------------------
    $MinLen = 8;
    $R = "bug: oops";
    if       (strlen($password) < $MinLen) {
       $R =  __("The password is too short.");
    } elseif (strtolower($user_name) == strtolower($password)) {
       $R =  __("The User name and password can't be the same!");
    } elseif (!$is_number_found) {
       $R =  __("The password must contain a digit.");
    } elseif (!$is_lowercase_found) {
       $R =  __("The password must contain a lower case character.");
    } elseif (!$is_uppercase_found) {
       $R =  __("The password must contain an upper case character.");
    } elseif (!$is_symbol_found) {
       $R =  __("The password must contain a symbol (such as '@' or '#' etc).");
    } else {
       $R = '';  //Password good
    }
    if  ($R != '')
        $R = $R .  __("  The requirements for an acceptable password are that they must be at least ") . $MinLen .  __(" characters long and contain at least one each of [1] digits, [2] symbols, [3] lower case and [4] upper case");
    return $R;
}




No comments: