web-dev-qa-db-fra.com

Le mot de passe de l'utilisateur est vide

Remarque: en réalité, la situation décrite concerne un environnement local. J'aimerais savoir ce qui se passe si ça passe en direct avec ce réglage.

J'ai installé un plugin qui a réinitialisé tous les mots de passe de la base de données WP. Tous les mots de passe des utilisateurs existants sont donc vides. J'ai généré un nouveau mot de passe pour mon utilisateur personnel. À propos des autres utilisateurs, puis-je laisser le mot de passe vide dans la base de données ou est-ce dangereux? J'ai remarqué que si j'essaie de me connecter avec un mot de passe vide, la connexion est impossible dans wordpress.

3
testermaster

Je ne le recommanderais toujours pas car il est probablement exploitable d'une manière ou d'une autre ...

Techniquement, en supposant que tous les raccordements et fonctions appropriés soient appelés, un utilisateur ne devrait pas pouvoir se connecter s’il fournit un mot de passe vide, même si le champ user_pass de la base de données est vide.

Pourquoi...?

Lorsque vous essayez de vous connecter à l'aide du formulaire tel qu'il apparaît sur /wp-login./php, WordPress appelle wp_authenticate_username_password() qui est accrochée à l'action authenticate.

wp_authenticate_username_password() vérifie si le $password soumis n'est pas vide. S'il est vide, il lève une instance de WP_Error et la demande de connexion sera rejetée.

La même chose s’applique où que vous essayiez de vous connecter, qu’il s’agisse d’un formulaire de connexion personnalisé ou non, en supposant que les hooks ou fonctions appropriés soient appelés, par exemple. authenticate ou wp_authenticate_username_password().

Désormais, même si vous atteignez le point wp_check_password() de wp_authenticate_username_password(), un mot de passe vide génère toujours une valeur de hachage lorsqu’il est exécuté via md5(), par exemple. md5('') //d41d8cd98f00b204e9800998ecf8427e.

Donc, ce qui se passe lorsque nous entrons dans la fonction wp_check_password() est que la logique suivante est exécutée ...

Source: wp-includes/pluggable.php

function wp_check_password($password, $hash, $user_id = '') {
    global $wp_hasher;

//note that...
//$password  = '' and $hash (from db) = ''

// If the hash is still md5...
if ( strlen($hash) <= 32 ) {
    $check = hash_equals( $hash, md5( $password ) ); // <- $check will return false, because the $hash is empty and does not match the hash of md5($password)

    if ( $check && $user_id ) {
        // Rehash using new hash.
        wp_set_password($password, $user_id);
        $hash = wp_hash_password($password);
    }

    /**
     * Filter whether the plaintext password matches the encrypted password.
     *
     * @since 2.5.0
     *
     * @param bool   $check    Whether the passwords match.
     * @param string $password The plaintext password.
     * @param string $hash     The hashed password.
     * @param int    $user_id  User ID.
     */
    return apply_filters( 'check_password', $check, $password, $hash, $user_id );
}


// If the stored hash is longer than an MD5, presume the
// new style phpass portable hash.
if ( empty($wp_hasher) ) {
    require_once( ABSPATH . WPINC . '/class-phpass.php');
    // By default, use the portable hash from phpass
    $wp_hasher = new PasswordHash(8, true);
}

$check = $wp_hasher->CheckPassword($password, $hash);

/** This filter is documented in wp-includes/pluggable.php */
return apply_filters( 'check_password', $check, $password, $hash, $user_id );

}

Ok donc une fois que nous avons frappé:

if ( strlen($hash) <= 32 ) {
    $check = hash_equals( $hash, md5( $password ) );

$check renverra false car la valeur de $hash est une chaîne vide et la valeur de md5($password), qui est essentiellement md5(''), est d41d8cd98f00b204e9800998ecf8427e comme indiqué ci-dessus.

Par conséquent, la tentative de connexion sera rejetée.

Donc, en théorie, vous êtes en sécurité sauf si un code malveillant s’accroît:

return apply_filters( 'check_password', $check, $password, $hash, $user_id );

... et retourne true. Mais n'importe qui peut le faire dans des circonstances normales où des hachages de mots de passe appropriés existent dans la base de données.

Recommandation:

Le fait de laisser le champ user_pass dans la base de données vide et vide de hachages est une mauvaise pratique.

Assumer que quelqu'un savait que tous les mots de passe de la base de données étaient vierges et voulait vous faire foirer, ils seraient à mi-chemin en le faisant. Tout ce qu'ils ont à faire, c'est trouver un moyen d'exploiter le système.

Étant donné qu'il est peu probable que vous ayez audité chaque partie du code interne, ainsi que du code des plugins et probablement de votre thème, vous ne savez pas quand ou si des mots de passe vierges vont revenir vous piquer au cul à cause de certains cas zéro exploit qui est introduit.

Au lieu...

//you can use get_users() if you prefer instead of $wpdb directly...
//this is just a one time operation.. don't forget to exclude those
//users whom you do not wish to reset a password for, e.g. yourself

global $wpdb;

$users = $wpdb->get_col("SELECT ID FROM {$wpdb->prefix}users WHERE 1 = 1");

foreach ($users as $user_id) {
    wp_set_password(wp_generate_password(), $user_id);
}

... faites-vous une faveur en définissant des mots de passe pour tous les utilisateurs et en leur permettant de réinitialiser le mot de passe ou de générer un courrier électronique contenant un lien de réinitialisation du mot de passe.

1
userabuser