0

I am trying to use Recaptcha v2 to defend against brute force. I have got the recaptcha all set up and working so that the user needs to verify every time they login. HOWEVER, when attempting an automated brute force, the attack is still successful. I know this is because they can use the original recaptcha response from their first login and use it every time. So what I am asking is how can I make it so it needs to match the new verification each time? Maybe getting a response when the captcha expires?? here is my html code:

<div class="g-recaptcha" data-sitekey="6LdRT5QUAAAAAD_BucIv7sDUhLE7iVtHRUR9LyhM"></div>
              <br/>

PHP:

     $secret = 'my secret';
        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
        $responseData = json_decode($verifyResponse);

    echo $responseData;

        if($responseData->success)

    {



            if ($state->num_rows == 1)

     {
        $row[]=array($firstName, $lastName);    
        echo json_encode($state);
        $_SESSION['uName'] = $uName;

     }
            else {
                echo ("false");
        }


 } 
    else {
                echo ("false");
        }

}

Thanks in advance.

morganp
  • 13
  • 1
  • 3
  • "I know this is because they can use the original recaptcha response from their first login and use it every time" if this is hte case there is something wrong in your code, you need to share that –  Mar 18 '19 at 20:22
  • thanks for your response tim. They cannot do that when they are trying to login regularly (manually) it is only when running a brute force attack as the program saves the original recaptcha response and continues to use it for every attempt? So im wondering how to make that statement only successful if it matches the NEW response? – morganp Mar 18 '19 at 20:33
  • 1
    if that's your full code your doing it really wrong, you send g-recaptcha-response to a google api for validation, please read the documentation https://developers.google.com/recaptcha/docs/verify –  Mar 18 '19 at 20:37
  • 2
    So it would appear that the problem is just that I am not validating it properly? – morganp Mar 18 '19 at 20:42
  • 1
    your not validating at all. `$cap1 = $_POST["g-recaptcha-response"];` then `if($cap1 == $_POST["g-recaptcha-response"] ..` will always be true. $_POST["g-recaptcha-response"] needs to be sent to the google api for validation –  Mar 18 '19 at 20:46
  • 1
    lots of examples out there, i chose this one randomly: http://acmeextension.com/integrate-google-recaptcha-with-php/ –  Mar 18 '19 at 20:51
  • Thanks tim, updated my code to use the code from that answer (please see updated question), yet it is always returning false any ideas? – morganp Mar 19 '19 at 19:52
  • what exactly is the result from `echo $responseData;` ? –  Mar 19 '19 at 20:06

1 Answers1

0

There are two things wrong with your code.

1. You need a new token on each load

You can refresh the reCAPTCHA by calling the reCAPTCHA API on each time the page is loaded.

Each reCAPTCHA user response token can only be verified once. If you need a new token, you will need to call grecaptcha.reset() to ask the end user to verify with reCAPTCHA again.

grecaptcha.reset( opt_widget_id ) Resets the reCAPTCHA widget. opt_widget_id Optional widget ID, defaults to the first widget created if unspecified.

<script type="text/javascript">
  $(document).ready(function() {
    grecaptcha.reset();
  });
</script>

2. You aren't verifing the reCAPTCHA response

You need to POST the following information to : https://www.google.com/recaptcha/api/siteverify

METHOD: POST

POST Parameter Description
secret Required. The shared key between your site and reCAPTCHA.
response Required. The user response token provided by the reCAPTCHA client-side integration on your site.
remoteip Optional. The user's IP address.

When you post the 2-3 pieces to the website you will get a JSON object back. In that object it will have the key, 'success'. If that is true then they are validated.

The 'success' should be in your PHP if statement.

Sources: API-Request JS-API Verifying-Response

Haley Mueller
  • 487
  • 4
  • 16
  • Thanks mark that makes sense, I have updated my code (please see question) in attempt to make use from that 'success' however it is always still returning 'false' any ideas? – morganp Mar 19 '19 at 19:53
  • You are on the right track. You are using the method GET instead of POST for the google URL. Look at this question's answer to see how to send a POST request to a url. https://stackoverflow.com/questions/3080146/post-data-to-a-url-in-php – Haley Mueller Mar 19 '19 at 20:42
  • absolutely brilliant, took your advice and used the POST instead of GET, along with help from this answer: https://stackoverflow.com/a/50253981/8002915 and it now works verifying correctly, preventing brute force! thanks ! – morganp Mar 19 '19 at 21:26
  • @morganp since it's working could you click the ✓ on my answer to verify that it worked. I'm glad it worked! – Haley Mueller Mar 19 '19 at 21:34