• caglararli@hotmail.com
  • 05386281520

Automated bot/spammer bypassing google recaptcha v2

Çağlar Arlı      -    44 Views

Automated bot/spammer bypassing google recaptcha v2

I have a Laravel registration form with the invisible google recaptcha v2 installed with the security set to highest level within the recaptcha admin console - code as follows:

<div>
  <div class="js-recaptcha-holder"></div>
    <button type="submit">Create account</button>
    {!! errors_for('g-recaptcha-response', $errors) !!}
  </div>
</div>

The javascript:

var captchaSiteKey = window['CAPTCHA_SITEKEY'] || false

win.renderGoogleInvisibleRecaptcha = function() {

    if (!captchaSiteKey) {
        console.error('No captcha sitekey available to implement reCaptcha')
        return
    }

    for (var i = 0; i < document.forms.length; ++i) {
        var form = document.forms[i];
        var holder = form.querySelector('.js-recaptcha-holder');
        if (null === holder) {
            continue;
        }

        (function(frm) {

            var holderId = grecaptcha.render(holder, {
                'sitekey': captchaSiteKey,
                'size': 'invisible',
                'badge': 'bottomright', // possible values: bottomright, bottomleft, inline
                'callback': function(recaptchaToken) {
                    HTMLFormElement.prototype.submit.call(frm);
                }
            });


            frm.onsubmit = function(evt) {
                evt.preventDefault();
                grecaptcha.execute(holderId);

            };

        })(form);
    }
};

Reviewing the access logs I notice a spammer/bot/automated programme hitting the form with a couple hundred fake submissions daily using up bandwidth.

In a normal scenario when using a browser the user/bot would be forced to solve the challenge before they can submit the form. How is the user bypassing the recaptcha? The google recaptcha admin console doesn't have any failed attempts. The captcha works if I try to submit the form i.e. the challenge is presented before you can submit form

These are some recent logs:

189.41.110.180  --  [01/Apr/2023:02:38:28   +0000]  GET / HTTP/1.1                  301 178 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:32   +0000]  GET / HTTP/1.1                  301 178 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:36   +0000]  GET / HTTP/1.1                  200 22327   -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:39   +0000]  GET /user/login HTTP/1.1    200 6188    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:40   +0000]  POST /user/login HTTP/1.1   302 430 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:41   +0000]  GET /user/login HTTP/1.1    200 6352    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:42   +0000]  POST /user/login HTTP/1.1   302 430 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:43   +0000]  GET /user/login HTTP/1.1    200 6352    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:44   +0000]  POST /user/login HTTP/1.1   302 430 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:45   +0000]  GET /user/login HTTP/1.1        200 6352    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:46   +0000]  POST /user/register HTTP/1.1    302 442 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:47   +0000]  GET /user/register HTTP/1.1 200 6395    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:48   +0000]  POST /user/register HTTP/1.1    302 442 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:49   +0000]  GET /user/register HTTP/1.1 200 6383    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:50   +0000]  POST /user/register HTTP/1.1    302 442 -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
189.41.110.180  --  [01/Apr/2023:02:38:51   +0000]  GET /user/register HTTP/1.1 200 6395    -   Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36

The logs show user is managing to post the form/payload but getting a 302 which I think is the server side validation kicking in as the recaptcha would be missing from payload or are they actually managing to bypass the captcha somehow and some other server side form validation is redirecting back to the form with 302?

The form has a CSRF token so I would have expected to see 419 status code in the access logs if they were using something like curl to send the payload?

The user attempts the same with the login form. On that I've implemented login throttling but user still keeps making attempts - they simply get a 302 message as the server side validation/throttling kicks in.

I was thinking about blocking their IP using something like fail2ban but the user keeps rotating their IP address.

Is their any other suggestion how I can prevent this malicious user/bot submitting the form.

Any help advice appreciated.

*** Update ***

I added some logging to the form and it seems the bot is managing to post the form bypassing the recaptcha as the payload would include the recapture response token so I suspect its using a programmatic mechanism to submit the form. Below is example of their payload and the server side validation kicking in.

[2023-04-03 00:49:04] production.ERROR: Validation failed for IP 115.84.79.60 with data: {"_token":"DF2q8mTYWYl99W2NFM92xmDlQ3Y20hYxdrzw1YK1","first_name":"GrwCsTLWYq","last_name":"ogbLBjqX","email":"digjicahan@outlook.com","password":"iL7ghtnp0INc!","password_confirmation":"iL7ghtnp0INc!","remember":"true","site_marketing":"true","third_party_marketing":"true","text_only_email":"true","terms_accepted":"true"}. Error: Password must be at least 8 characters long and contain both letters and numbers  
[2023-04-03 00:49:09] production.ERROR: Validation failed for IP 115.84.79.60 with data: {"_token":"DF2q8mTYWYl99W2NFM92xmDlQ3Y20hYxdrzw1YK1","first_name":"JRbSlutIjCH","last_name":"GhfOYXIWgKB","email":"digjicahan@outlook.com","password":"WdGHfMXvwpUz!","password_confirmation":"WdGHfMXvwpUz!","remember":"true","site_marketing":"true","third_party_marketing":"true","text_only_email":"true","terms_accepted":"true"}. Error: Password must be at least 8 characters long and contain both letters and numbers 

I suppose my question is how is the csrf token in that payload still valid. I attempted to replicate the same using curl to initially do a curl GET request of the page and grab the CSRF token and then immediately submit a curl POST attempt using that csrf token and it always returns a 419 error?