Security: Reintroduce support for passwords hashed with MD5.

This reinstates the ability for a user to log in to an account where the password is hashed using MD5. This means that the ability to reset a password directly in the database using an SQL query or a database administration tool will be retained without the need to implement or integrate with bcrypt or phpass.

A password hashed with MD5 will get upgraded to bcrypt at the point where a user successfully logs in, just as is the case with a phpass hash.

Props audrasjb, aaronjorbin, johnbillion, david-innes, benniledl.

See #21022.
Built from https://develop.svn.wordpress.org/trunk@59893


git-svn-id: http://core.svn.wordpress.org/trunk@59235 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
John Blackbourn 2025-02-28 18:53:23 +00:00
parent b024026e81
commit d75f025337
2 changed files with 18 additions and 23 deletions

View File

@ -2724,7 +2724,6 @@ if ( ! function_exists( 'wp_check_password' ) ) :
* @since 2.5.0
* @since 6.8.0 Passwords in WordPress are now hashed with bcrypt by default. A
* password that wasn't hashed with bcrypt will be checked with phpass.
* Passwords hashed with md5 are no longer supported.
*
* @global PasswordHash $wp_hasher phpass object. Used as a fallback for verifying
* passwords that were hashed with phpass.
@ -2742,30 +2741,14 @@ if ( ! function_exists( 'wp_check_password' ) ) :
) {
global $wp_hasher;
$check = false;
// If the hash is still md5 or otherwise truncated then invalidate it.
if ( strlen( $hash ) <= 32 ) {
/**
* Filters whether the plaintext password matches the hashed password.
*
* @since 2.5.0
* @since 6.8.0 Passwords are now hashed with bcrypt by default.
* Old passwords may still be hashed with phpass.
*
* @param bool $check Whether the passwords match.
* @param string $password The plaintext password.
* @param string $hash The hashed password.
* @param string|int $user_id Optional ID of a user associated with the password.
* Can be empty.
*/
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
}
if ( ! empty( $wp_hasher ) ) {
// Check the hash using md5 regardless of the current hashing mechanism.
$check = hash_equals( $hash, md5( $password ) );
} elseif ( ! empty( $wp_hasher ) ) {
// Check the password using the overridden hasher.
$check = $wp_hasher->CheckPassword( $password, $hash );
} elseif ( strlen( $password ) > 4096 ) {
// Passwords longer than 4096 characters are not supported.
$check = false;
} elseif ( str_starts_with( $hash, '$wp' ) ) {
// Check the password using the current prefixed hash.
@ -2780,7 +2763,19 @@ if ( ! function_exists( 'wp_check_password' ) ) :
$check = password_verify( $password, $hash );
}
/** This filter is documented in wp-includes/pluggable.php */
/**
* Filters whether the plaintext password matches the hashed password.
*
* @since 2.5.0
* @since 6.8.0 Passwords are now hashed with bcrypt by default.
* Old passwords may still be hashed with phpass or md5.
*
* @param bool $check Whether the passwords match.
* @param string $password The plaintext password.
* @param string $hash The hashed password.
* @param string|int $user_id Optional ID of a user associated with the password.
* Can be empty.
*/
return apply_filters( 'check_password', $check, $password, $hash, $user_id );
}
endif;

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.8-alpha-59892';
$wp_version = '6.8-alpha-59893';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.