@@ -529,7 +529,12 @@ public static function get_user_two_factor_revalidate_url( $interim = false ) {
529529 * @return boolean
530530 */
531531 public static function is_valid_user_action ( $ user_id , $ action ) {
532- $ request_nonce = isset ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_NONCE_QUERY_ARG ] ) ? wp_unslash ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_NONCE_QUERY_ARG ] ) : '' ;
532+ $ request_nonce_raw = isset ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_NONCE_QUERY_ARG ] ) ? wp_unslash ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_NONCE_QUERY_ARG ] ) : '' ; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Value sanitized and then only passed to wp_verify_nonce().
533+ if ( ! is_scalar ( $ request_nonce_raw ) ) {
534+ $ request_nonce = '' ;
535+ } else {
536+ $ request_nonce = sanitize_text_field ( (string ) $ request_nonce_raw );
537+ }
533538
534539 if ( ! $ user_id || ! $ action || ! $ request_nonce ) {
535540 return false ;
@@ -550,8 +555,8 @@ public static function is_valid_user_action( $user_id, $action ) {
550555 */
551556 public static function current_user_being_edited () {
552557 // Try to resolve the user ID from the request first.
553- if ( ! empty ( $ _REQUEST ['user_id ' ] ) ) {
554- $ user_id = intval ( $ _REQUEST ['user_id ' ] );
558+ if ( ! empty ( $ _REQUEST ['user_id ' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in trigger_user_settings_action() via is_valid_user_action() before any state change.
559+ $ user_id = intval ( $ _REQUEST ['user_id ' ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in trigger_user_settings_action() via is_valid_user_action() before any state change.
555560
556561 if ( current_user_can ( 'edit_user ' , $ user_id ) ) {
557562 return $ user_id ;
@@ -570,8 +575,9 @@ public static function current_user_being_edited() {
570575 * @return void
571576 */
572577 public static function trigger_user_settings_action () {
573- $ action = isset ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_QUERY_VAR ] ) ? wp_unslash ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_QUERY_VAR ] ) : '' ;
574- $ user_id = self ::current_user_being_edited ();
578+ $ action_raw = isset ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_QUERY_VAR ] ) ? wp_unslash ( $ _REQUEST [ self ::USER_SETTINGS_ACTION_QUERY_VAR ] ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Value sanitized below; nonce verified in is_valid_user_action() before do_action.
579+ $ action = ( is_scalar ( $ action_raw ) && (string ) $ action_raw !== '' ) ? sanitize_key ( (string ) $ action_raw ) : '' ;
580+ $ user_id = self ::current_user_being_edited ();
575581
576582 if ( self ::is_valid_user_action ( $ user_id , $ action ) ) {
577583 /**
@@ -984,7 +990,7 @@ public static function show_two_factor_login( $user ) {
984990 wp_die ( esc_html__ ( 'Failed to create a login nonce. ' , 'two-factor ' ) );
985991 }
986992
987- $ redirect_to = isset ( $ _REQUEST ['redirect_to ' ] ) ? $ _REQUEST ['redirect_to ' ] : admin_url ();
993+ $ redirect_to = isset ( $ _REQUEST ['redirect_to ' ] ) ? esc_url_raw ( wp_unslash ( $ _REQUEST ['redirect_to ' ] ) ) : admin_url (); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Value only used for redirect; auth protected by 2FA login nonce later.
988994
989995 self ::login_html ( $ user , $ login_nonce ['key ' ], $ redirect_to );
990996 }
@@ -1038,6 +1044,12 @@ public static function maybe_show_reset_password_notice( $errors ) {
10381044 return $ errors ;
10391045 }
10401046
1047+ // Verify login form nonce when present (e.g. wp-login.php); skip only when nonce is not sent (custom login forms).
1048+ if ( isset ( $ _POST ['_wpnonce ' ] ) && ! wp_verify_nonce ( sanitize_text_field ( wp_unslash ( $ _POST ['_wpnonce ' ] ) ), 'log-in ' ) ) {
1049+ return $ errors ;
1050+ }
1051+
1052+ // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified above when _wpnonce present; absent for custom login forms.
10411053 $ user_name = sanitize_user ( wp_unslash ( $ _POST ['log ' ] ) );
10421054 $ attempted_user = get_user_by ( 'login ' , $ user_name );
10431055 if ( ! $ attempted_user && str_contains ( $ user_name , '@ ' ) ) {
@@ -1558,11 +1570,11 @@ public static function rest_api_can_edit_user_and_update_two_factor_options( $us
15581570 * @since 0.2.0
15591571 */
15601572 public static function login_form_validate_2fa () {
1561- $ wp_auth_id = ! empty ( $ _REQUEST ['wp-auth-id ' ] ) ? absint ( $ _REQUEST ['wp-auth-id ' ] ) : 0 ;
1562- $ nonce = ! empty ( $ _REQUEST ['wp-auth-nonce ' ] ) ? wp_unslash ( $ _REQUEST ['wp-auth-nonce ' ] ) : '' ;
1563- $ provider = ! empty ( $ _REQUEST ['provider ' ] ) ? wp_unslash ( $ _REQUEST ['provider ' ] ) : '' ;
1564- $ redirect_to = ! empty ( $ _REQUEST ['redirect_to ' ] ) ? wp_unslash ( $ _REQUEST ['redirect_to ' ] ) : '' ;
1565- $ is_post_request = ( ' POST ' === strtoupper ( $ _SERVER ['REQUEST_METHOD ' ] ) );
1573+ $ wp_auth_id = ! empty ( $ _REQUEST ['wp-auth-id ' ] ) ? absint ( $ _REQUEST ['wp-auth-id ' ] ) : 0 ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_validate_2fa() via verify_login_nonce() before any use.
1574+ $ nonce = ( isset ( $ _REQUEST ['wp-auth-nonce ' ] ) && is_scalar ( $ _REQUEST [ ' wp-auth-nonce ' ] ) ) ? sanitize_text_field ( wp_unslash ( ( string ) $ _REQUEST ['wp-auth-nonce ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_validate_2fa() before any use.
1575+ $ provider = ! empty ( $ _REQUEST ['provider ' ] ) ? sanitize_text_field ( wp_unslash ( $ _REQUEST ['provider ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_validate_2fa() before any use.
1576+ $ redirect_to = ! empty ( $ _REQUEST ['redirect_to ' ] ) ? esc_url_raw ( wp_unslash ( $ _REQUEST ['redirect_to ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_validate_2fa() before any use.
1577+ $ is_post_request = isset ( $ _SERVER [ ' REQUEST_METHOD ' ] ) && ' POST ' === strtoupper ( $ _SERVER ['REQUEST_METHOD ' ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- REQUEST_METHOD is not user input.
15661578 $ user = get_user_by ( 'id ' , $ wp_auth_id );
15671579
15681580 if ( ! $ wp_auth_id || ! $ nonce || ! $ user ) {
@@ -1624,7 +1636,7 @@ public static function _login_form_validate_2fa( $user, $nonce = '', $provider =
16241636 delete_user_meta ( $ user ->ID , self ::USER_FAILED_LOGIN_ATTEMPTS_KEY );
16251637
16261638 $ rememberme = false ;
1627- if ( isset ( $ _REQUEST ['rememberme ' ] ) && $ _REQUEST [ ' rememberme ' ] ) {
1639+ if ( ! empty ( $ _REQUEST ['rememberme ' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Request read only after successful verify_login_nonce() in this request.
16281640 $ rememberme = true ;
16291641 }
16301642
@@ -1665,7 +1677,7 @@ public static function _login_form_validate_2fa( $user, $nonce = '', $provider =
16651677 $ interim_login = isset ( $ _REQUEST ['interim-login ' ] ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited,WordPress.Security.NonceVerification.Recommended
16661678
16671679 if ( $ interim_login ) {
1668- $ customize_login = isset ( $ _REQUEST ['customize-login ' ] );
1680+ $ customize_login = isset ( $ _REQUEST ['customize-login ' ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Request read only after successful verify_login_nonce() in this request.
16691681 if ( $ customize_login ) {
16701682 wp_enqueue_script ( 'customize-base ' );
16711683 wp_add_inline_script (
@@ -1699,10 +1711,10 @@ public static function _login_form_validate_2fa( $user, $nonce = '', $provider =
16991711 * @since 0.9.0
17001712 */
17011713 public static function login_form_revalidate_2fa () {
1702- $ nonce = ! empty ( $ _REQUEST ['wp-auth-nonce ' ] ) ? wp_unslash ( $ _REQUEST ['wp-auth-nonce ' ] ) : '' ;
1703- $ provider = ! empty ( $ _REQUEST ['provider ' ] ) ? sanitize_text_field ( wp_unslash ( $ _REQUEST ['provider ' ] ) ) : false ;
1704- $ redirect_to = ! empty ( $ _REQUEST ['redirect_to ' ] ) ? wp_unslash ( $ _REQUEST ['redirect_to ' ] ) : admin_url ();
1705- $ is_post_request = ( ' POST ' === strtoupper ( $ _SERVER ['REQUEST_METHOD ' ] ) );
1714+ $ nonce = ( isset ( $ _REQUEST ['wp-auth-nonce ' ] ) && is_scalar ( $ _REQUEST [ ' wp-auth-nonce ' ] ) ) ? sanitize_text_field ( wp_unslash ( ( string ) $ _REQUEST ['wp-auth-nonce ' ] ) ) : '' ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_revalidate_2fa() for POST before processing.
1715+ $ provider = ! empty ( $ _REQUEST ['provider ' ] ) ? sanitize_text_field ( wp_unslash ( $ _REQUEST ['provider ' ] ) ) : false ; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_revalidate_2fa() for POST before processing.
1716+ $ redirect_to = ! empty ( $ _REQUEST ['redirect_to ' ] ) ? esc_url_raw ( wp_unslash ( $ _REQUEST ['redirect_to ' ] ) ) : admin_url (); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified in _login_form_revalidate_2fa() for POST before processing.
1717+ $ is_post_request = isset ( $ _SERVER [ ' REQUEST_METHOD ' ] ) && ' POST ' === strtoupper ( $ _SERVER ['REQUEST_METHOD ' ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- REQUEST_METHOD is not user input.
17061718
17071719 self ::_login_form_revalidate_2fa ( $ nonce , $ provider , $ redirect_to , $ is_post_request );
17081720 exit ;
@@ -2559,11 +2571,7 @@ public static function get_current_user_session() {
25592571 * @return boolean
25602572 */
25612573 public static function rememberme () {
2562- $ rememberme = false ;
2563-
2564- if ( ! empty ( $ _REQUEST ['rememberme ' ] ) ) {
2565- $ rememberme = true ;
2566- }
2574+ $ rememberme = ! empty ( $ _REQUEST ['rememberme ' ] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Non-destructive display/flow flag; value normalized to bool below.
25672575
25682576 /**
25692577 * Filters whether the login session should persist between browser sessions.
0 commit comments