reCAPTCHA v3 not working in form with ajax elements

Created on 26 April 2023, over 1 year ago
Updated 17 September 2024, 11 days ago

Problem/Motivation

I have tried to add Recaptcha v3 to a form with multiple Ajax elements, but I always get the fallback challenge on submission no matter how low the threshold is.
After debugging, I could find the cause of the issue. The function recaptcha_v3_pre_captcha_element_process() is replacing the challenge type and setting the temporary value of recaptcha_v3_action_name every time an ajax element is triggered, this is because checking the $form_state->isProcessingInput() is not enough to determine if the form is been submitted. Therefore, the element post-process function thinks the form was already submitted and runs the recaptcha_v3_validate on every Ajax request. If this function is called multiple times (multiple Ajax requests are made before submitting the form), the validation fails due to timeout-or-duplicate when the form is submitted since it is using the same recaptcha v3 response.

Steps to reproduce

  1. Create a new form base on FormBase class.
  2. Add a button (not submit type) field with ajax.
  3. Add a new Recatpcha v3 action (does not matter the threshold).
  4. Configure the form to use the new action.
  5. Navegate to the form and press the ajax button multiple times.
  6. Submit the form.
  7. The fallback challenge will appear no matter how low have you set the threshold.

Proposed resolution

Check the triggeredElement on the captcha element pre-process function to determine if the form was submitted before changing the challenge or setting the temporary variable.

πŸ› Bug report
Status

Closed: works as designed

Version

1.8

Component

Code

Created by

πŸ‡¨πŸ‡΄Colombia s_castro

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @s_castro
  • πŸ‡¨πŸ‡΄Colombia s_castro

    I made a patch that works for me.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.0.7 + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    1 pass
  • πŸ‡ΊπŸ‡¦Ukraine dench0

    @s_castro

    It looks like the problem is not in the module but with the captcha "cacheable" feature.
    On Ajax call it should work like this: it validates the reCAPTCHA v3 response and if validation passes, then the captcha element is not added to the returned form at all.

    Can you pls check this:
    1. Set Math as a fallback challenge.
    2. Disable "Cacheable" in the reCAPTCHA v3 settings.

  • πŸ‡¨πŸ‡΄Colombia s_castro

    @dench0,

    Thanks for the quick response.
    I tested it again following your recommendation. I already had the "cacheable" checkbox disabled, but it worked when I changed the fallback challenge from reCAPTCHA to Math. For some reason adding reCAPTCHA as the fallback challenge makes the function recaptcha_v3_validate execute multiple times, while the Math executes the function just once (the first time an Ajax element is triggered).

    Do you know with this is only a problem with reCAPTCHA as fallback challenge?

    In both cases, the validation function is executed the first time an Ajax element is triggered instead of being called on the form submit. I am not sure if this is the expected behavior.

  • πŸ‡ΊπŸ‡¦Ukraine dench0

    The reCAPTCHA module not working very well with Ajax forms due to the enabled cacheable feature.

    You can verify this by using directly the reCAPTCHA captcha for your form: solve the reCAPTCHA and hit that Ajax button. Depending on what your Ajax callback returns (the entire form or only part of the form) you can get one of two cases:

    1. The new unsolved reCAPTCHA element.
    2. reCAPTCHA element stays solved but you will get a captcha error on the form submission.

    I think you can discover reCAPTCHA issues for a possible solution (or create a new one if any exists). Or you can solve it by yourself: in hook_form_alter you need to unset or set to false reCAPTCHA cacheable: https://git.drupalcode.org/project/recaptcha/-/blob/8.x-3.x/recaptcha.mo....

    I'll try to solve this on the reCAPTCHA V3 side, but only for the 2.0 version.

  • πŸ‡¨πŸ‡΄Colombia s_castro

    Thanks for your help. It seems to be an issue with the reCaptcha module. Disabling the cacheable feature in a hook_form_alter worked for me.

  • πŸ‡ΊπŸ‡¦Ukraine dench0

    I have created a patch to move the cacheable property to the "action" entity. Then in the element process hook, it overwrites the fallback challenge "captcha_cacheable" by the action cacheable property.
    But then changed my mind and don't think it was a good idea.

    I left the patch file here just in case.

  • Status changed to Closed: works as designed about 1 year ago
  • πŸ‡ΊπŸ‡¦Ukraine dench0

    Close this issue as the problem is not in the reCAPTCHA v3, but in the reCAPTCHA module.

Production build 0.71.5 2024