PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.6
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.6
3.4.6 3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 All 199 releases
← All changes | includes/class-convertkit-recaptcha.php +69 -9 3.3.1 → 3.4.6 View file →
@@ -71,9 +71,9 @@
71 71 * @param string $recaptcha_response The reCAPTCHA response.
72 72 * @param string $plugin_action The action to verify the reCAPTCHA response for.
73 73 * @return bool|WP_Error
74 74 */
75 - public function verify_recaptcha( $recaptcha_response, $plugin_action ) {
75 + public function verify( $recaptcha_response, $plugin_action ) {
76 76
77 77 // Don't run if the reCAPTCHA or scripts are disabled.
78 78 if ( ! $this->settings->has_recaptcha_site_and_secret_keys() || $this->settings->scripts_disabled() ) {
79 79 return true;
@@ -90,9 +90,9 @@
90 90 ),
91 91 )
92 92 );
93 93
94 - // Bail if an error occured.
94 + // Bail if an error occurred.
95 95 if ( is_wp_error( $response ) ) {
96 96 return $response;
97 97 }
98 98
@@ -98,28 +98,39 @@
98 98
99 99 // Inspect response.
100 100 $body = json_decode( wp_remote_retrieve_body( $response ), true );
101 101
102 + // If the response body couldn't be decoded, treat that as a failure.
103 + if ( ! is_array( $body ) ) {
104 + return new WP_Error(
105 + 'convertkit_recaptcha_failed',
106 + __( 'Google reCAPTCHA failure: invalid response from siteverify.', 'convertkit' )
107 + );
108 + }
109 +
102 110 // If the request wasn't successful, return an error.
103 - if ( ! $body['success'] ) {
111 + if ( empty( $body['success'] ) ) {
104 112 return new WP_Error(
105 113 'convertkit_recaptcha_failed',
106 114 sprintf(
107 115 /* translators: Error codes */
108 116 __( 'Google reCAPTCHA failure: %s', 'convertkit' ),
109 - implode( ', ', $body['error-codes'] )
117 + implode( ', ', isset( $body['error-codes'] ) ? (array) $body['error-codes'] : array() )
110 118 )
111 119 );
112 120 }
113 121
114 - // Return if the action doesn't match the Plugin action, this might not be a reCAPTCHA request
115 - // for this request.
116 - if ( $body['action'] !== $plugin_action ) {
117 - return true;
122 + // If the action doesn't match the Plugin action, the token was generated for a different action.
123 + // Treat this as a failure, so the minimum score check can't be bypassed.
124 + if ( ! isset( $body['action'] ) || $body['action'] !== $plugin_action ) {
125 + return new WP_Error(
126 + 'convertkit_recaptcha_failed',
127 + __( 'Google reCAPTCHA failed', 'convertkit' )
128 + );
118 129 }
119 130
120 131 // If the score is less than the required minimum score, it's likely a spam submission.
121 - if ( $body['score'] < $this->settings->recaptcha_minimum_score() ) {
132 + if ( ! isset( $body['score'] ) || $body['score'] < $this->settings->recaptcha_minimum_score() ) {
122 133 return new WP_Error(
123 134 'convertkit_recaptcha_failed',
124 135 __( 'Google reCAPTCHA failed', 'convertkit' )
125 136 );
@@ -126,8 +137,57 @@
126 137 }
127 138
128 139 // If here, the submission looks genuine. Continue the request.
129 140 return true;
141 +
142 + }
143 +
144 + /**
145 + * Attaches the reCAPTCHA v3 invisible-badge attributes to the given submit
146 + * button element within an existing DOM tree, so that the challenge is
147 + * executed when the button is clicked and the form is submitted via the
148 + * `convertKitRecaptchaFormSubmit` callback.
149 + *
150 + * @since 3.3.7
151 + *
152 + * @param ConvertKit_HTML_Parser $parser Parser wrapping the DOM (unused).
153 + * @param DOMElement $button <button> element to attach attributes to.
154 + * @param string $plugin_action Plugin action string.
155 + */
156 + public function attach_to_form_button_dom( $parser, $button, $plugin_action ) {
157 +
158 + unset( $parser );
159 +
160 + $button->setAttribute( 'data-sitekey', esc_attr( $this->settings->recaptcha_site_key() ) );
161 + $button->setAttribute( 'data-callback', 'convertKitRecaptchaFormSubmit' );
162 + $button->setAttribute( 'data-action', $plugin_action );
163 + $button->setAttribute( 'class', trim( $button->getAttribute( 'class' ) . ' g-recaptcha' ) );
164 +
165 + }
166 +
167 + /**
168 + * Returns the HTML for a submit button with reCAPTCHA v3 invisible-badge
169 + * attributes attached, used by templates that don't have a DOM parser
170 + * available (e.g. the Restrict Content tag view).
171 + *
172 + * @since 3.3.7
173 + *
174 + * @param string $label Button's visible label.
175 + * @param string $plugin_action Plugin action string.
176 + * @param string[] $css_classes CSS classes for the button.
177 + * @return string
178 + */
179 + public function get_submit_button_html( $label, $plugin_action, $css_classes = array() ) {
180 +
181 + $css_classes[] = 'g-recaptcha';
182 +
183 + return sprintf(
184 + '<input type="submit" class="%1$s" value="%2$s" data-sitekey="%3$s" data-callback="convertKitRecaptchaFormSubmit" data-action="%4$s" />',
185 + esc_attr( implode( ' ', $css_classes ) ),
186 + esc_attr( $label ),
187 + esc_attr( $this->settings->recaptcha_site_key() ),
188 + esc_attr( $plugin_action )
189 + );
130 190
131 191 }
132 192
133 193 }