Search code examples
javascriptajaxspringjsprecaptcha

How do I load reCAPTCHA Score and Checkbox on the same page?


Currently on a login page, I need to have both the score and checkbox reCaptcha evaluation on the same page, if the score fails I need to dynamically load the checkbox score.

Currently I have it working although I don't know if I implemented it correctly.

In my HTML header I have

<script src="https://www.google.com/recaptcha/enterprise.js?render=${Login.reCaptchaScoreKey}"></script>

and in the html body I have

<script src="https://www.google.com/recaptcha/enterprise.js?render=explicit"></script>

In AJAX to load the checkbox I have:

 var captchaContainer = grecaptcha.render('captcha_container', {
              'sitekey' : siteKey,
              'callback' : function() {
                $("#LOGIN").prop('disabled', false);
              }
});

and to submit the score I have the following (I'm attaching the reCaptcha generated token to an HTML element since it was the only way I could figure out to send it to my backend):

grecaptcha.enterprise.ready(function() {
                grecaptcha.enterprise.execute(scoreKey, {action: action}).then(function(token) {
                    $('#g-recaptcha-response').val(token);
                    submitForm();
                });
              });

It seems strange that I need to include the reCaptcha JS file twice for this to work which is a bit of a code smell. If I remove the first JS file as expected my score reCaptcha breaks, if I remove the second my checkbox breaks.

Is there a way to do what I want to do by including the reCaptcha JS only once? Or is the way that I'm doing it okay?


Solution

  • I received an official response for the reCAPTCHA Enterprise support team:

    Thanks for reaching out here. We recommend not putting a checkbox behind a score. More details are available on this here: https://cloud.google.com/recaptcha-enterprise/docs/faq#id_like_to_use_the_score_from_to_show_a_challenge_checkbox_widget_how_can_i_do_this

    Not only are there concerns listed in that FAQ point about the efficacy of a checkbox widget when placed behind a score, but it also over simplifies how the checkbox widget works. We perform "adversarial challenging" on our checkbox widget (essentially, we show harder challenges to known attackers), but we're unable to do so when placed behind a score reCAPTCHA.

    All of this being said, if you do wish to do it anyway, you would have to include the JS file twice.

    And this is from the link posted in their email:

    I'd like to use the score from reCAPTCHA Enterprise to show a challenge / checkbox widget. How can I do this?

    We recommend that you do not do this. reCAPTCHA Enterprise expects to see both good and bad user behavior on implementation. If you trigger a reCAPTCHA Enterprise checkbox widget based on a reCAPTCHA Enterprise score, the checkbox widget is only being exposed to bad traffic. Due to this, the widget can have a more difficult time determining whether to show a challenge or not. This can result in issuing NO CAPTCHAs (no challenge shown at all) to fraudulent users or bots due to trouble making that differentiation.

    In these cases, we recommend just using a challenge-based site key upfront (like reCAPTCHA Enterprise with a CHECKBOX Site Key) instead, but installing a SCORE Site Key on every page, as well as issuing grecaptcha.enterprise.execute to train the model, but foregoing assessments on the SCORE tokens. Essentially, this achieves the goal by training the reCAPTCHA Enterprise CHECKBOX site keys on user behavior, resulting in less challenges shown to legitimate users and more challenges to fraudulent ones.