| @@ -525,15 +525,16 @@ | ||
| 525 | 525 | } |
| 526 | 526 | |
| 527 | 527 | } |
| 528 | 528 | |
| 529 | - // Save valid results when they are being triggered from an ajax request | |
| 530 | - if( wp_doing_ajax() && isset( $_POST['action'] ) && $_POST['action'] == 'pms_validate_checkout' ){ | |
| 529 | + // Save valid results when they are being triggered from an ajax request that only pre-validates the | |
| 530 | + // credentials, so the same single use token is still accepted on the form submission that follows it | |
| 531 | + if( wppb_is_captcha_prevalidation_request() ){ | |
| 531 | 532 | |
| 532 | - $saved = get_option( 'wppb_recaptcha_validations', array() ); | |
| 533 | + $saved = wppb_prune_captcha_prevalidations( get_option( 'wppb_recaptcha_validations', array() ) ); | |
| 533 | 534 | |
| 534 | 535 | if( $already_validated === true ) |
| 535 | - $saved[ $recaptcha_response_field ] = true; | |
| 536 | + $saved[ $recaptcha_response_field ] = time(); | |
| 536 | 537 | |
| 537 | 538 | update_option( 'wppb_recaptcha_validations', $saved, false ); |
| 538 | 539 | |
| 539 | 540 | } |
| @@ -791,37 +792,37 @@ | ||
| 791 | 792 | if ( isset( $_POST['log'] ) && !is_wp_error($user) && !isset( $_POST['pms_login'] ) ) { |
| 792 | 793 | |
| 793 | 794 | $field = wppb_get_recaptcha_field(); |
| 794 | 795 | if ( !empty($field) ){ |
| 795 | - global $wppb_recaptcha_response; | |
| 796 | + /* Work out whether reCAPTCHA is enabled for the form that was actually submitted before verifying | |
| 797 | + anything. The token is single use, so verifying it on a form where our widget was never displayed | |
| 798 | + spends a token that belongs to whatever else protects that form, and that plugin's own check | |
| 799 | + then fails as a duplicate. */ | |
| 800 | + if ( isset($_POST['wppb_login']) && ($_POST['wppb_login'] == true) ) { | |
| 801 | + // it's a PB login form, check if we have a reCAPTCHA on it | |
| 802 | + $recaptcha_enabled = ( isset($field['captcha-pb-forms']) && ( strpos($field['captcha-pb-forms'], 'pb_login') !== false || ( $field['recaptcha-type'] == 'v3' && wppb_maybe_enable_recaptcha_v3_on_form( $field ) ) ) ); | |
| 803 | + } | |
| 804 | + else { | |
| 805 | + // default WP login form | |
| 806 | + $recaptcha_enabled = ( isset($field['captcha-wp-forms']) && (strpos($field['captcha-wp-forms'], 'default_wp_login') !== false) ); | |
| 807 | + } | |
| 796 | 808 | |
| 797 | - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 809 | + if ( $recaptcha_enabled ) { | |
| 810 | + global $wppb_recaptcha_response; | |
| 798 | 811 | |
| 799 | - $recaptcha_error_message = __('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 812 | + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 800 | 813 | |
| 801 | - if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 802 | - $recaptcha_error_message = __('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 803 | - } | |
| 814 | + $recaptcha_error_message = __('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 804 | 815 | |
| 805 | - //reCAPTCHA error for displaying on the PB login form | |
| 806 | - if ( isset($_POST['wppb_login']) && ($_POST['wppb_login'] == true) ) { | |
| 807 | - | |
| 808 | - // it's a PB login form, check if we have a reCAPTCHA on it and display error if not valid | |
| 809 | - if ((isset($field['captcha-pb-forms'])) && (strpos($field['captcha-pb-forms'], 'pb_login') !== false || ( $field['recaptcha-type'] == 'v3' && wppb_maybe_enable_recaptcha_v3_on_form( $field ) ) ) && ($wppb_recaptcha_response == false)) { | |
| 810 | - $user = new WP_Error('wppb_recaptcha_error', $recaptcha_error_message); | |
| 811 | - remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 ); | |
| 812 | - remove_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 ); | |
| 816 | + if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 817 | + $recaptcha_error_message = __('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 813 | 818 | } |
| 814 | 819 | |
| 815 | - } | |
| 816 | - else { | |
| 817 | - //reCAPTCHA error for displaying on the default WP login form | |
| 818 | - if (isset($field['captcha-wp-forms']) && (strpos($field['captcha-wp-forms'], 'default_wp_login') !== false) && ($wppb_recaptcha_response == false)) { | |
| 820 | + if ( $wppb_recaptcha_response == false ) { | |
| 819 | 821 | $user = new WP_Error('wppb_recaptcha_error', $recaptcha_error_message); |
| 820 | 822 | remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 ); |
| 821 | 823 | remove_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 ); |
| 822 | 824 | } |
| 823 | - | |
| 824 | 825 | } |
| 825 | 826 | } |
| 826 | 827 | } |
| 827 | 828 | return $user; |
| @@ -882,22 +883,25 @@ | ||
| 882 | 883 | return; |
| 883 | 884 | |
| 884 | 885 | $field = wppb_get_recaptcha_field(); |
| 885 | 886 | if ( !empty($field) ){ |
| 886 | - global $wppb_recaptcha_response; | |
| 887 | - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 887 | + /* Only verify where the captcha is configured for the form being submitted. The token is single use, | |
| 888 | + so verifying it on a form our widget was never displayed on spends a token that another plugin | |
| 889 | + protecting that form still needs, and its own check then fails as a duplicate. */ | |
| 890 | + if ( isset( $field['captcha-wp-forms'] ) && ( strpos( $field['captcha-wp-forms'], 'default_wp_recover_password' ) !== false ) ) { | |
| 891 | + global $wppb_recaptcha_response; | |
| 892 | + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 888 | 893 | |
| 889 | - $recaptcha_error_message = esc_html__('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 894 | + $recaptcha_error_message = esc_html__('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 890 | 895 | |
| 891 | - if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 892 | - $recaptcha_error_message = esc_html__('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 893 | - } | |
| 896 | + if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 897 | + $recaptcha_error_message = esc_html__('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 898 | + } | |
| 894 | 899 | |
| 895 | - // Fail closed, but only where reCAPTCHA is configured for this form. Gate on captcha-wp-forms (as the | |
| 896 | - // login path does) instead of isset() of the token, so a missing token is treated as a failed verification | |
| 897 | - // without blocking default WP password recovery on sites that only use reCAPTCHA on PB forms. | |
| 898 | - if ( isset( $field['captcha-wp-forms'] ) && ( strpos( $field['captcha-wp-forms'], 'default_wp_recover_password' ) !== false ) && ( $wppb_recaptcha_response == false ) ) { | |
| 899 | - wp_die( esc_html( $recaptcha_error_message ) . '<br />' . esc_html__( "Click the BACK button on your browser, and try again.", 'profile-builder' ) ) ; | |
| 900 | + // Fail closed: a missing token is treated as a failed verification. | |
| 901 | + if ( $wppb_recaptcha_response == false ) { | |
| 902 | + wp_die( esc_html( $recaptcha_error_message ) . '<br />' . esc_html__( "Click the BACK button on your browser, and try again.", 'profile-builder' ) ) ; | |
| 903 | + } | |
| 900 | 904 | } |
| 901 | 905 | } |
| 902 | 906 | } |
| 903 | 907 | add_action('lostpassword_post','wppb_verify_recaptcha_default_wp_recover_password'); |
| @@ -938,22 +942,25 @@ | ||
| 938 | 942 | function wppb_verify_recaptcha_default_wp_register( $errors ){ |
| 939 | 943 | |
| 940 | 944 | $field = wppb_get_recaptcha_field(); |
| 941 | 945 | if ( !empty($field) ){ |
| 942 | - global $wppb_recaptcha_response; | |
| 943 | - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 946 | + /* Only verify where the captcha is configured for the form being submitted. The token is single use, | |
| 947 | + so verifying it on a form our widget was never displayed on spends a token that another plugin | |
| 948 | + protecting that form still needs, and its own check then fails as a duplicate. */ | |
| 949 | + if ( isset( $field['captcha-wp-forms'] ) && ( strpos( $field['captcha-wp-forms'], 'default_wp_register' ) !== false ) ) { | |
| 950 | + global $wppb_recaptcha_response; | |
| 951 | + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ), isset( $field['score-threshold'] ) ? trim( $field['score-threshold'] ) : 0.5 ); | |
| 944 | 952 | |
| 945 | - $recaptcha_error_message = esc_html__('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 953 | + $recaptcha_error_message = esc_html__('reCaptcha could not be verified. Please try again.','profile-builder'); | |
| 946 | 954 | |
| 947 | - if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 948 | - $recaptcha_error_message = esc_html__('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 949 | - } | |
| 955 | + if( isset( $field['recaptcha-type'] ) && $field['recaptcha-type'] === 'v2' ) { | |
| 956 | + $recaptcha_error_message = esc_html__('Please enter a (valid) reCAPTCHA value','profile-builder'); | |
| 957 | + } | |
| 950 | 958 | |
| 951 | - // Fail closed, but only where reCAPTCHA is configured for this form. Gate on captcha-wp-forms (as the | |
| 952 | - // login path does) instead of isset() of the token, so a missing token is treated as a failed verification | |
| 953 | - // without blocking default WP registration on sites that only use reCAPTCHA on PB forms. | |
| 954 | - if ( isset( $field['captcha-wp-forms'] ) && ( strpos( $field['captcha-wp-forms'], 'default_wp_register' ) !== false ) && ( $wppb_recaptcha_response == false ) ) { | |
| 955 | - $errors->add( 'wppb_recaptcha_error', $recaptcha_error_message ); | |
| 959 | + // Fail closed: a missing token is treated as a failed verification. | |
| 960 | + if ( $wppb_recaptcha_response == false ) { | |
| 961 | + $errors->add( 'wppb_recaptcha_error', $recaptcha_error_message ); | |
| 962 | + } | |
| 956 | 963 | } |
| 957 | 964 | } |
| 958 | 965 | |
| 959 | 966 | return $errors; |