wp/wp-includes/class-wp-recovery-mode-key-service.php
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
--- 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 );
 	}
 }