Skip to content

Fix reCAPTCHA - #1211

Draft
n7studios wants to merge 1 commit into
mainfrom
fix-recaptcha
Draft

n7studios wants to merge 1 commit into
mainfrom
fix-recaptcha

Conversation

@n7studios

Copy link
Copy Markdown
Contributor

Summary

Fixes several issues with spam protection (Google reCAPTCHA v3 and Cloudflare Turnstile) on the Form Builder block, Restrict Content tag form and Member Content login form:

  • reCAPTCHA score check could be bypassed. ConvertKit_Recaptcha::verify() returned true when the token's action didn't match the form's action, skipping the minimum score check. A token generated for any other action passed verification. A mismatched or missing action now fails with the same Google reCAPTCHA failed error as a low score. A missing score is also treated as a failure. Each form's submit button and server-side check already use the same action, so genuine submissions aren't affected.
  • PHP errors on unexpected siteverify responses. If Google or Cloudflare returned an unsuccessful response without error-codes, implode() threw a TypeError. Both providers now handle a missing error-codes. reCAPTCHA also handles a response body that isn't valid JSON. Turnstile also handles a response with no success key.
  • reCAPTCHA submitted the wrong form when a Page had multiple forms. convertKitRecaptchaFormSubmit() always submitted the first reCAPTCHA protected form on the Page. For example, with two Form Builder blocks, or a Form Builder block and a Restrict Content tag form, clicking the second form's button submitted the first form. The clicked submit button is now stored, and its form is submitted.

Testing

New Integration tests in SpamProtectionTest, mocking Google's and Cloudflare's siteverify responses:

  • testRecaptchaValidToken
  • testRecaptchaLowScore
  • testRecaptchaActionMismatch
  • testRecaptchaNoAction
  • testRecaptchaFailureWithErrorCodes
  • testRecaptchaFailureWithNoErrorCodes
  • testRecaptchaInvalidResponse
  • testCloudflareTurnstileValidToken
  • testCloudflareTurnstileFailureWithNoErrorCodes
  • testCloudflareTurnstileNoSuccess

All of these except testRecaptchaValidToken, testRecaptchaLowScore, testRecaptchaFailureWithErrorCodes and testCloudflareTurnstileValidToken fail on main.

New E2E test, PageBlockFormBuilderCest::testFormBuilderWithRecaptchaEnabledSubmitsClickedForm:

  • Adds two Form Builder blocks to a Page and clicks the second form's submit button.
  • Then calls the reCAPTCHA callback.
  • Confirms the second form is submitted. On main, the first form is submitted.

The existing reCAPTCHA E2E tests in PageBlockFormBuilderCest, RestrictContentTagCest and RestrictContentMemberContentLoginCest use real keys from CI secrets, so they need to pass in CI to confirm genuine submissions aren't affected.

Checklist

@n7studios n7studios added this to the 3.4.6 milestone Oct 1, 2026
@n7studios n7studios self-assigned this Oct 1, 2026
@n7studios n7studios added the bug label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

WordPress Playground

🚀 Your PR has been built and is ready for testing in WordPress Playground!

Click here to test your changes in WordPress Playground

@n7studios
n7studios marked this pull request as ready for review October 1, 2026 11:23
@n7studios
n7studios requested review from a team, ciccio-kit and noelherrick and removed request for a team October 1, 2026 11:23
@n7studios
n7studios marked this pull request as draft October 2, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1 participant