diff -r 48c4eec2b7e6 -r 8c2e4d02f4ef wp/wp-includes/class-wp-recovery-mode-key-service.php --- a/wp/wp-includes/class-wp-recovery-mode-key-service.php Fri Sep 05 18:40:08 2025 +0200 +++ b/wp/wp-includes/class-wp-recovery-mode-key-service.php Fri Sep 05 18:52:52 2025 +0200 @@ -37,29 +37,18 @@ * Creates a recovery mode key. * * @since 5.2.0 - * - * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance. + * @since 6.8.0 The stored key is now hashed using wp_fast_hash() instead of phpass. * * @param string $token A token generated by {@see generate_recovery_mode_token()}. * @return string Recovery mode key. */ public function generate_and_store_recovery_mode_key( $token ) { - - global $wp_hasher; - $key = wp_generate_password( 22, false ); - if ( empty( $wp_hasher ) ) { - require_once ABSPATH . WPINC . '/class-phpass.php'; - $wp_hasher = new PasswordHash( 8, true ); - } - - $hashed = $wp_hasher->HashPassword( $key ); - $records = $this->get_keys(); $records[ $token ] = array( - 'hashed_key' => $hashed, + 'hashed_key' => wp_fast_hash( $key ), 'created_at' => time(), ); @@ -85,16 +74,12 @@ * * @since 5.2.0 * - * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance. - * * @param string $token The token used when generating the given key. - * @param string $key The unhashed key. + * @param string $key The plain text key. * @param int $ttl Time in seconds for the key to be valid for. * @return true|WP_Error True on success, error object on failure. */ public function validate_recovery_mode_key( $token, $key, $ttl ) { - global $wp_hasher; - $records = $this->get_keys(); if ( ! isset( $records[ $token ] ) ) { @@ -109,12 +94,7 @@ return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) ); } - if ( empty( $wp_hasher ) ) { - require_once ABSPATH . WPINC . '/class-phpass.php'; - $wp_hasher = new PasswordHash( 8, true ); - } - - if ( ! $wp_hasher->CheckPassword( $key, $record['hashed_key'] ) ) { + if ( ! wp_verify_fast_hash( $key, $record['hashed_key'] ) ) { return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) ); } @@ -169,9 +149,20 @@ * Gets the recovery key records. * * @since 5.2.0 + * @since 6.8.0 Each key is now hashed using wp_fast_hash() instead of phpass. + * Existing keys may still be hashed using phpass. * - * @return array Associative array of $token => $data pairs, where $data has keys 'hashed_key' - * and 'created_at'. + * @return array { + * Associative array of token => data pairs, where the data is an associative + * array of information about the key. + * + * @type array ...$0 { + * Information about the key. + * + * @type string $hashed_key The hashed value of the key. + * @type int $created_at The timestamp when the key was created. + * } + * } */ private function get_keys() { return (array) get_option( $this->option_name, array() ); @@ -181,12 +172,22 @@ * Updates the recovery key records. * * @since 5.2.0 + * @since 6.8.0 Each key should now be hashed using wp_fast_hash() instead of phpass. * - * @param array $keys Associative array of $token => $data pairs, where $data has keys 'hashed_key' - * and 'created_at'. + * @param array $keys { + * Associative array of token => data pairs, where the data is an associative + * array of information about the key. + * + * @type array ...$0 { + * Information about the key. + * + * @type string $hashed_key The hashed value of the key. + * @type int $created_at The timestamp when the key was created. + * } + * } * @return bool True on success, false on failure. */ private function update_keys( array $keys ) { - return update_option( $this->option_name, $keys ); + return update_option( $this->option_name, $keys, false ); } }