Make WordPress Core


Ignore:
Timestamp:
02/17/2025 11:22:33 AM (3 months ago)
Author:
johnbillion
Message:

Security: Switch to using bcrypt for hashing user passwords and BLAKE2b for hashing application passwords and security keys.

Passwords and security keys that were saved in prior versions of WordPress will continue to work. Each user's password will be opportunistically rehashed and resaved when they next subsequently log in using a valid password.

The following new functions have been introduced:

  • wp_password_needs_rehash()
  • wp_fast_hash()
  • wp_verify_fast_hash()

The following new filters have been introduced:

  • password_needs_rehash
  • wp_hash_password_algorithm
  • wp_hash_password_options

Props ayeshrajans, bgermann, dd32, deadduck169, desrosj, haozi, harrym, iandunn, jammycakes, joehoyle, johnbillion, mbijon, mojorob, mslavco, my1xt, nacin, otto42, paragoninitiativeenterprises, paulkevan, rmccue, ryanhellyer, scribu, swalkinshaw, synchro, th23, timothyblynjacobs, tomdxw, westi, xknown.

Additional thanks go to the Roots team, Soatok, Calvin Alkan, and Raphael Ahrens.

Fixes #21022, #44628

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-recovery-mode-key-service.php

    r58975 r59828  
    3838     *
    3939     * @since 5.2.0
    40      *
    41      * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
     40     * @since 6.8.0 The stored key is now hashed using wp_fast_hash() instead of phpass.
    4241     *
    4342     * @param string $token A token generated by {@see generate_recovery_mode_token()}.
     
    4544     */
    4645    public function generate_and_store_recovery_mode_key( $token ) {
    47 
    48         global $wp_hasher;
    49 
    5046        $key = wp_generate_password( 22, false );
    51 
    52         if ( empty( $wp_hasher ) ) {
    53             require_once ABSPATH . WPINC . '/class-phpass.php';
    54             $wp_hasher = new PasswordHash( 8, true );
    55         }
    56 
    57         $hashed = $wp_hasher->HashPassword( $key );
    5847
    5948        $records = $this->get_keys();
    6049
    6150        $records[ $token ] = array(
    62             'hashed_key' => $hashed,
     51            'hashed_key' => wp_fast_hash( $key ),
    6352            'created_at' => time(),
    6453        );
     
    8675     * @since 5.2.0
    8776     *
    88      * @global PasswordHash $wp_hasher Portable PHP password hashing framework instance.
    89      *
    9077     * @param string $token The token used when generating the given key.
    91      * @param string $key   The unhashed key.
     78     * @param string $key   The plain text key.
    9279     * @param int    $ttl   Time in seconds for the key to be valid for.
    9380     * @return true|WP_Error True on success, error object on failure.
    9481     */
    9582    public function validate_recovery_mode_key( $token, $key, $ttl ) {
    96         global $wp_hasher;
    97 
    9883        $records = $this->get_keys();
    9984
     
    11095        }
    11196
    112         if ( empty( $wp_hasher ) ) {
    113             require_once ABSPATH . WPINC . '/class-phpass.php';
    114             $wp_hasher = new PasswordHash( 8, true );
    115         }
    116 
    117         if ( ! $wp_hasher->CheckPassword( $key, $record['hashed_key'] ) ) {
     97        if ( ! wp_verify_fast_hash( $key, $record['hashed_key'] ) ) {
    11898            return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) );
    11999        }
     
    170150     *
    171151     * @since 5.2.0
     152     * @since 6.8.0 Each key is now hashed using wp_fast_hash() instead of phpass.
     153     *              Existing keys may still be hashed using phpass.
    172154     *
    173      * @return array Associative array of $token => $data pairs, where $data has keys 'hashed_key'
    174      *               and 'created_at'.
     155     * @return array {
     156     *     Associative array of token => data pairs, where the data is an associative
     157     *     array of information about the key.
     158     *
     159     *     @type array ...$0 {
     160     *         Information about the key.
     161     *
     162     *         @type string $hashed_key The hashed value of the key.
     163     *         @type int    $created_at The timestamp when the key was created.
     164     *     }
     165     * }
    175166     */
    176167    private function get_keys() {
     
    182173     *
    183174     * @since 5.2.0
     175     * @since 6.8.0 Each key should now be hashed using wp_fast_hash() instead of phpass.
    184176     *
    185      * @param array $keys Associative array of $token => $data pairs, where $data has keys 'hashed_key'
    186      *                    and 'created_at'.
     177     * @param array $keys {
     178     *     Associative array of token => data pairs, where the data is an associative
     179     *     array of information about the key.
     180     *
     181     *     @type array ...$0 {
     182     *         Information about the key.
     183     *
     184     *         @type string $hashed_key The hashed value of the key.
     185     *         @type int    $created_at The timestamp when the key was created.
     186     *     }
     187     * }
    187188     * @return bool True on success, false on failure.
    188189     */
Note: See TracChangeset for help on using the changeset viewer.