--- 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 );
}
}