Changeset 59828 for trunk/src/wp-includes/pluggable.php
- Timestamp:
- 02/17/2025 11:22:33 AM (3 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/pluggable.php
r59803 r59828 694 694 * @param string $cookie Optional. If used, will validate contents instead of cookie's. 695 695 * @param string $scheme Optional. The cookie scheme to use: 'auth', 'secure_auth', or 'logged_in'. 696 * Note: This does *not* default to 'auth' like other cookie functions. 696 697 * @return int|false User ID if valid cookie, false if invalid. 697 698 */ … … 769 770 } 770 771 771 $pass_frag = substr( $user->user_pass, 8, 4 ); 772 if ( str_starts_with( $user->user_pass, '$P$' ) || str_starts_with( $user->user_pass, '$2y$' ) ) { 773 // Retain previous behaviour of phpass or vanilla bcrypt hashed passwords. 774 $pass_frag = substr( $user->user_pass, 8, 4 ); 775 } else { 776 // Otherwise, use a substring from the end of the hash to avoid dealing with potentially long hash prefixes. 777 $pass_frag = substr( $user->user_pass, -4 ); 778 } 772 779 773 780 $key = wp_hash( $username . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme ); … … 870 877 } 871 878 872 $pass_frag = substr( $user->user_pass, 8, 4 ); 879 if ( str_starts_with( $user->user_pass, '$P$' ) || str_starts_with( $user->user_pass, '$2y$' ) ) { 880 // Retain previous behaviour of phpass or vanilla bcrypt hashed passwords. 881 $pass_frag = substr( $user->user_pass, 8, 4 ); 882 } else { 883 // Otherwise, use a substring from the end of the hash to avoid dealing with potentially long hash prefixes. 884 $pass_frag = substr( $user->user_pass, -4 ); 885 } 873 886 874 887 $key = wp_hash( $user->user_login . '|' . $pass_frag . '|' . $expiration . '|' . $token, $scheme ); … … 2626 2639 * 2627 2640 * @since 2.5.0 2628 * 2629 * @global PasswordHash $wp_hasher PHPass object. 2641 * @since 6.8.0 The password is now hashed using bcrypt by default instead of phpass. 2642 * 2643 * @global PasswordHash $wp_hasher phpass object. 2630 2644 * 2631 2645 * @param string $password Plain text user password to hash. … … 2638 2652 global $wp_hasher; 2639 2653 2640 if ( empty( $wp_hasher ) ) { 2641 require_once ABSPATH . WPINC . '/class-phpass.php'; 2642 // By default, use the portable hash from phpass. 2643 $wp_hasher = new PasswordHash( 8, true ); 2644 } 2645 2646 return $wp_hasher->HashPassword( trim( $password ) ); 2654 if ( ! empty( $wp_hasher ) ) { 2655 return $wp_hasher->HashPassword( trim( $password ) ); 2656 } 2657 2658 if ( strlen( $password ) > 4096 ) { 2659 return '*'; 2660 } 2661 2662 /** 2663 * Filters the hashing algorithm to use in the password_hash() and password_needs_rehash() functions. 2664 * 2665 * The default is the value of the `PASSWORD_BCRYPT` constant which means bcrypt is used. 2666 * 2667 * **Important:** The only password hashing algorithm that is guaranteed to be available across PHP 2668 * installations is bcrypt. If you use any other algorithm you must make sure that it is available on 2669 * the server. The `password_algos()` function can be used to check which hashing algorithms are available. 2670 * 2671 * The hashing options can be controlled via the {@see 'wp_hash_password_options'} filter. 2672 * 2673 * Other available constants include: 2674 * 2675 * - `PASSWORD_ARGON2I` 2676 * - `PASSWORD_ARGON2ID` 2677 * - `PASSWORD_DEFAULT` 2678 * 2679 * @since 6.8.0 2680 * 2681 * @param string $algorithm The hashing algorithm. Default is the value of the `PASSWORD_BCRYPT` constant. 2682 */ 2683 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT ); 2684 2685 /** 2686 * Filters the options passed to the password_hash() and password_needs_rehash() functions. 2687 * 2688 * The default hashing algorithm is bcrypt, but this can be changed via the {@see 'wp_hash_password_algorithm'} 2689 * filter. You must ensure that the options are appropriate for the algorithm in use. 2690 * 2691 * @since 6.8.0 2692 * 2693 * @param array $options Array of options to pass to the password hashing functions. 2694 * By default this is an empty array which means the default 2695 * options will be used. 2696 * @param string $algorithm The hashing algorithm in use. 2697 */ 2698 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm ); 2699 2700 // Algorithms other than bcrypt don't need to use pre-hashing. 2701 if ( PASSWORD_BCRYPT !== $algorithm ) { 2702 return password_hash( $password, $algorithm, $options ); 2703 } 2704 2705 // Use SHA-384 to retain entropy from a password that's longer than 72 bytes, and a `wp-sha384` key for domain separation. 2706 $password_to_hash = base64_encode( hash_hmac( 'sha384', trim( $password ), 'wp-sha384', true ) ); 2707 2708 // Add a prefix to facilitate distinguishing vanilla bcrypt hashes. 2709 return '$wp' . password_hash( $password_to_hash, $algorithm, $options ); 2647 2710 } 2648 2711 endif; … … 2652 2715 * Checks a plaintext password against a hashed password. 2653 2716 * 2654 * Maintains compatibility between old version and the new cookie authentication 2655 * protocol using PHPass library. The $hash parameter is the encrypted password 2656 * and the function compares the plain text password when encrypted similarly 2657 * against the already encrypted password to see if they match. 2717 * Note that this function may be used to check a value that is not a user password. 2718 * A plugin may use this function to check a password of a different type, and there 2719 * may not always be a user ID associated with the password. 2658 2720 * 2659 2721 * For integration with other applications, this function can be overwritten to … … 2661 2723 * 2662 2724 * @since 2.5.0 2663 * 2664 * @global PasswordHash $wp_hasher PHPass object used for checking the password 2665 * against the $hash + $password. 2666 * @uses PasswordHash::CheckPassword 2667 * 2668 * @param string $password Plaintext user's password. 2669 * @param string $hash Hash of the user's password to check against. 2670 * @param string|int $user_id Optional. User ID. 2725 * @since 6.8.0 Passwords in WordPress are now hashed with bcrypt by default. A 2726 * password that wasn't hashed with bcrypt will be checked with phpass. 2727 * Passwords hashed with md5 are no longer supported. 2728 * 2729 * @global PasswordHash $wp_hasher phpass object. Used as a fallback for verifying 2730 * passwords that were hashed with phpass. 2731 * 2732 * @param string $password Plaintext password. 2733 * @param string $hash Hash of the password to check against. 2734 * @param string|int $user_id Optional. ID of a user associated with the password. 2671 2735 * @return bool False, if the $password does not match the hashed password. 2672 2736 */ … … 2679 2743 global $wp_hasher; 2680 2744 2681 // If the hash is still md5... 2745 $check = false; 2746 2747 // If the hash is still md5 or otherwise truncated then invalidate it. 2682 2748 if ( strlen( $hash ) <= 32 ) { 2683 $check = hash_equals( $hash, md5( $password ) );2684 if ( $check && $user_id ) {2685 // Rehash using new hash.2686 wp_set_password( $password, $user_id );2687 $hash = wp_hash_password( $password );2688 }2689 2690 2749 /** 2691 * Filters whether the plaintext password matches the encrypted password.2750 * Filters whether the plaintext password matches the hashed password. 2692 2751 * 2693 2752 * @since 2.5.0 2753 * @since 6.8.0 Passwords are now hashed with bcrypt by default. 2754 * Old passwords may still be hashed with phpass. 2694 2755 * 2695 2756 * @param bool $check Whether the passwords match. 2696 2757 * @param string $password The plaintext password. 2697 2758 * @param string $hash The hashed password. 2698 * @param string|int $user_id User ID. Can be empty. 2759 * @param string|int $user_id Optional ID of a user associated with the password. 2760 * Can be empty. 2699 2761 */ 2700 2762 return apply_filters( 'check_password', $check, $password, $hash, $user_id ); 2701 2763 } 2702 2764 2703 /* 2704 * If the stored hash is longer than an MD5, 2705 * presume the new style phpass portable hash. 2706 */ 2707 if ( empty( $wp_hasher ) ) { 2765 if ( ! empty( $wp_hasher ) ) { 2766 // Check the password using the overridden hasher. 2767 $check = $wp_hasher->CheckPassword( $password, $hash ); 2768 } elseif ( strlen( $password ) > 4096 ) { 2769 $check = false; 2770 } elseif ( str_starts_with( $hash, '$wp' ) ) { 2771 // Check the password using the current prefixed hash. 2772 $password_to_verify = base64_encode( hash_hmac( 'sha384', $password, 'wp-sha384', true ) ); 2773 $check = password_verify( $password_to_verify, substr( $hash, 3 ) ); 2774 } elseif ( str_starts_with( $hash, '$P$' ) ) { 2775 // Check the password using phpass. 2708 2776 require_once ABSPATH . WPINC . '/class-phpass.php'; 2709 // By default, use the portable hash from phpass.2710 $wp_hasher = new PasswordHash( 8, true );2711 }2712 2713 $check = $wp_hasher->CheckPassword( $password, $hash );2777 $check = ( new PasswordHash( 8, true ) )->CheckPassword( $password, $hash ); 2778 } else { 2779 // Check the password using compat support for any non-prefixed hash. 2780 $check = password_verify( $password, $hash ); 2781 } 2714 2782 2715 2783 /** This filter is documented in wp-includes/pluggable.php */ 2716 2784 return apply_filters( 'check_password', $check, $password, $hash, $user_id ); 2785 } 2786 endif; 2787 2788 if ( ! function_exists( 'wp_password_needs_rehash' ) ) : 2789 /** 2790 * Checks whether a password hash needs to be rehashed. 2791 * 2792 * Passwords are hashed with bcrypt using the default cost. A password hashed in a prior version 2793 * of WordPress may still be hashed with phpass and will need to be rehashed. If the default cost 2794 * or algorithm is changed in PHP or WordPress then a password hashed in a previous version will 2795 * need to be rehashed. 2796 * 2797 * Note that, just like wp_check_password(), this function may be used to check a value that is 2798 * not a user password. A plugin may use this function to check a password of a different type, 2799 * and there may not always be a user ID associated with the password. 2800 * 2801 * @since 6.8.0 2802 * 2803 * @global PasswordHash $wp_hasher phpass object. 2804 * 2805 * @param string $hash Hash of a password to check. 2806 * @param string|int $user_id Optional. ID of a user associated with the password. 2807 * @return bool Whether the hash needs to be rehashed. 2808 */ 2809 function wp_password_needs_rehash( $hash, $user_id = '' ) { 2810 global $wp_hasher; 2811 2812 if ( ! empty( $wp_hasher ) ) { 2813 return false; 2814 } 2815 2816 /** This filter is documented in wp-includes/pluggable.php */ 2817 $algorithm = apply_filters( 'wp_hash_password_algorithm', PASSWORD_BCRYPT ); 2818 2819 /** This filter is documented in wp-includes/pluggable.php */ 2820 $options = apply_filters( 'wp_hash_password_options', array(), $algorithm ); 2821 2822 $prefixed = str_starts_with( $hash, '$wp' ); 2823 2824 if ( ( PASSWORD_BCRYPT === $algorithm ) && ! $prefixed ) { 2825 // If bcrypt is in use and the hash is not prefixed then it needs to be rehashed. 2826 $needs_rehash = true; 2827 } else { 2828 // Otherwise check the hash minus its prefix if necessary. 2829 $hash_to_check = $prefixed ? substr( $hash, 3 ) : $hash; 2830 $needs_rehash = password_needs_rehash( $hash_to_check, $algorithm, $options ); 2831 } 2832 2833 /** 2834 * Filters whether the password hash needs to be rehashed. 2835 * 2836 * @since 6.8.0 2837 * 2838 * @param bool $needs_rehash Whether the password hash needs to be rehashed. 2839 * @param string $hash The password hash. 2840 * @param string|int $user_id Optional. ID of a user associated with the password. 2841 */ 2842 return apply_filters( 'password_needs_rehash', $needs_rehash, $hash, $user_id ); 2717 2843 } 2718 2844 endif; … … 2866 2992 * 2867 2993 * @since 2.5.0 2994 * @since 6.8.0 The password is now hashed using bcrypt by default instead of phpass. 2868 2995 * 2869 2996 * @global wpdb $wpdb WordPress database abstraction object.
Note: See TracChangeset
for help on using the changeset viewer.