eugbana
eugbana

Reputation: 37

Trying to implement the new Google CAPTCHA

For some reason, this implementation is meant to be easy, but I can't seem to get it right.

I have implemented in a form. Here is the link but the form still submits without validating the CAPTCHA. Here is my form processing page where the CAPTCHA validation is done.

I would appreciate it if someone could help me sort this out.

 <?php
 require_once('../Connections/conn.php'); 

// session_start();

// captcha validation
if(isset($_POST['submit'])){

$url="https://www.google.com/recaptcha/api/siteverify";
$privatekey='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$response = file_get_contents($url."?secret=".$privatekey."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']);

$data= json_decode($response);

}




?>


<!DOCTYPE html>
<!--[if (gte IE 9)|!(IE)]><!-->
<html lang="en">
<!--<![endif]-->
<head>

   <!-- Basic Page Needs
   ================================================== -->
   <meta charset="utf-8">
   <title>WOWSERVICE NIGERIA</title>
   <meta name="description" content="Extent - another WordPress theme">
   <meta name="author" content="Webnus">

   <!-- Mobile Specific Metas
   ================================================== -->
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

   <!-- CSS
   ================================================== -->
   <link rel="stylesheet" href="../css/style.css" type="text/css">
<link rel="stylesheet" href="../css/bootstrap.min.css" type="text/css">


<!-- <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:300italic,400italic,400,300,600,700,900|Varela|Arapey:400,400italic' rel="stylesheet" type='text/css' >-->

   <!-- JS
   ================================================== -->
   <script src="js/jquery.min.js" type="text/javascript"></script>
   <script src="layerslider/js/greensock.js" type="text/javascript"></script>
   <script src="SpryAssets/SpryValidationTextField.js" type="text/javascript"></script>
   <script src="SpryAssets/SpryValidationSelect.js" type="text/javascript"></script>
     <link rel="stylesheet" href="css/datepicker.css">




<!--[if lt IE 9]>
   <script src="../js/modernizr.custom.11889.js" type="text/javascript"></script>
   <script src="../js/respond.js" type="text/javascript"></script>
   <![endif]-->
   <!-- HTML5 Shiv events (end)-->
   <!-- MEGA MENU -->

   <!-- Favicons
   ================================================== -->
   <link rel="shortcut icon" href="images/favicon.ico">
   <link href="SpryAssets/SpryValidationTextField.css" rel="stylesheet" type="text/css">
   <link href="SpryAssets/SpryValidationSelect.css" rel="stylesheet" type="text/css">
</head>
<body class="yakisoba yakisoba-home">

<!-- Primary Page Layout
================================================== -->
<div id="wrap" class="boxed-wrap">

   <!-- Top Bar -->
   <section class="top-bar">
      <div class="container">
         <div class="top-links lftflot">
         <a href="#">About</a>
          <a href="#">Articles</a>
          <a href="#">Service News</a>
           <a href="#">Survey</a>
            <a href="#">Contact</a>
         </div>
         <div class="socialfollow rgtflot"><a href="" class="facebook"><i class="fa-facebook"></i></a><a href="" class="twitter"><i class="fa-twitter"></i></a><a href="" class="vimeo"><i class="fa-vimeo-square"></i></a></div>
     </div>
   </section> <!-- end top-bar -->

   <header id="header"  class="horizontal-w sm-rgt-mn">
      <div  class="container">
         <div class="col-md-7 col-sm-6 logo-wrap">
            <div class="logo">
               <a href="home.php"><img src="../images/logo.png" width="170" id="img-logo-w1" alt="logo" class="img-logo-w1"></a>
               <a href="home.php"><img src="../images/logo.png" width="130" id="img-logo-w2" alt="logo" class="img-logo-w2"></a>
            </div> <!-- end logo -->
         </div> <!-- end col-md-7 -->
         <div class="col-md-5 col-sm-6 alignright">
            <hr class="vertical-space" />
            <div class="widget">
               <div class="webnus-ad">
                  <a href="#"><img src="../images/homes/adv.jpg" alt="" /></a>          
                  <div class="clear"></div>
               </div>
           </div> <!-- end widget -->
         </div> <!-- end col-md-5 -->
      </div> <!-- end container -->
      <hr class="vertical-space" />
      <nav id="nav-wrap" class="nav-wrap2  mn4 darknavi">
         <div class="container">
            <ul id="nav">
               <li><a href="../post_complaint.php">Post Complaints</a></li>
               <li><a href="../post_commendation.php">Post Commendation</a></li>
               <li><a href="../request_report.php">Request for Report</a></li>
               <li><a href="../contact_details_upload.php">Upload Contact Details</a></li>
          <!--     <li><a href="#">Travel</a></li>-->
            </ul>
         </div> 
        <!-- end container -->
      </nav> <!-- nav wrap -->
   </header> <!-- end header -->
  <p></br></p>

    <div class="row">
        <div class="col-md-1"></div>

        <div class="col-md-10">

        <div class="bg-primary">

     <?php

     // if validation is successfull

     if(isset($data->success) AND $data->success==true){



       $query = $_POST['query']; 
    // gets value sent over search form

    $min_length = 3;
    // you can set minimum length of the query if you want

    if(strlen($query) >= $min_length){ // if query length is more or equal minimum length then

        $query = htmlspecialchars($query); 
        // changes characters used in html to their equivalents, for example: < to &gt;

        $query = mysql_real_escape_string($query);
        // makes sure nobody uses SQL injection

        $raw_results = mysql_query("SELECT * FROM request_report
            WHERE (`ticket` LIKE '%".$query."%')") or die(mysql_error());



        // * means that it selects all fields, you can also write: `id`, `title`, `text`
        // articles is the name of our table

        // '%$query%' is what we're looking for, % means anything, for example if $query is Hello
        // it will match "hello", "Hello man", "gogohello", if you want exact match use `title`='$query'
        // or if you want to match just full word so "gogohello" is out use '% $query %' ...OR ... '$query %' ... OR ... '% $query'

        if(mysql_num_rows($raw_results) > 0){ // if one or more rows are returned do following

            while($results = mysql_fetch_array($raw_results)){
            // $results = mysql_fetch_array($raw_results) puts data from database into array, while it's valid it does the loop
             if($results ['status']=='0'){
                echo "<p> The request associated with ticket number  <strong>" .$results['ticket']."</strong> is still being processed....</p>";
                // posts results gotten from database(title and text) you can also show id ($results['id'])
                }

                else if ($results ['status']=='1'){

                echo "<p> The request associated with ticket number  <strong>" .$results['ticket']."</strong> has been processed and closed....</p>";
                // posts results gotten from database(title and text) you can also show id ($results['id'])

                }
            }

        }
        else{ // if there is no matching rows do following
            echo "Sorry no results found <br>";
        }

    }
    else{ // if query length is less than minimum
        echo "Ticket number should be within  ".$min_length;
    }




    //retrieving data from complaints table



}
else{

$msg="Please re-enter your reCAPTCHA.";

}   
?>

Upvotes: 2

Views: 1123

Answers (4)

Igor Savinkin
Igor Savinkin

Reputation: 6277

the form still submits without validating the captcha

Form submits whatever is in it. If $_POST['g-recaptcha-response'] is from an unsolved/{wrongly solved} captcha, then at the server side when you verify site https://www.google.com/recaptcha/api/siteverify?... you get in response smth. like {success:false}. That's the prove that captcha is not valid; thus practically for a site owner (you) the captcha is verifyed server side. See more here.

Upvotes: 0

Chuck Le Butt
Chuck Le Butt

Reputation: 48818

I think you've gotten a bit confused as to how Google reCaptcha works -- it does not prevent a user POSTing data (a user could easily circumnavigate such a thing), it's used to allow server side code to check that the user is not a robot.

This means you have to have something on the server side to check what's being submitted, too. You can't just do it all client side. (Although it looks like Google is doing everything client side, the reCaptcha button is actually in an iframe, on another server.)

For example. see Google's demo here: https://www.google.com/recaptcha/api2/demo

Notice that it still POSTs the data back to the server when you click submit -- it's the server that responds to say whether you're human or not.

As Google's documentation states:

When your users submit the form where you integrated reCAPTCHA, you'll get as part of the payload a string with the name "g-recaptcha-response". In order to check whether Google has verified that user, send a POST request with these parameters:

URL: https://www.google.com/recaptcha/api/siteverify

secret (required) xxx
response (required) The value of 'g-recaptcha-response'.
remoteip The end user's ip address.

You basically need to check whether the POST request secret matches your secret key from your Recaptcha account. If it does, then you should give the user a download link, if it doesn't, return an error message.

You can learn more about this process in the reCaptcha documentation: https://developers.google.com/recaptcha/docs/verify


Clientside only

If you don't care about a someone being able fake the result, and want to stop the user submitting without trying to pass the Captcha you can do it using jQuery like so: JSFiddle

Upvotes: 0

Terabyte
Terabyte

Reputation: 455

Create a php file in the same directory as your form name it getCurlData.php and paste the following code and save

function getCurlData($url)
{
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16");
        $curlData = curl_exec($curl);
        curl_close($curl);
        return $curlData;
}

after that validate like this using the correct secrete-key and site-key

 $recaptcha=$_POST['g-recaptcha-response'];

        if(!empty($recaptcha))
        {
        include("getCurlData.php");
        $google_url="https://www.google.com/recaptcha/api/siteverify";
        $secret='put your key here';
        $ip=$_SERVER['REMOTE_ADDR'];
        $url=$google_url."?   secret=".$secret."&response=".$recaptcha."&remoteip=".$ip;
        $res=getCurlData($url);
        $res= json_decode($res, true);
        }
        else
        {
            $err_catpcha="* Verification error";
        }

Note this div is where the capture code will display

<div class="g-recaptcha" data-sitekey="you-sitekey-here"></div>

Upvotes: 0

Professor Abronsius
Professor Abronsius

Reputation: 33823

I hope the following will help, I have stripped down he code from my own example which does work.

On the page that has the captcha requirement
--------------------------------------------

head
----
<script type='text/javascript'>
    function verifyCaptcha(){
        /* 'grc' is the id of the placeholder DIV */
        grecaptcha.render( 'grc', {
            'sitekey'   :   'aaabbbcccdddeeefff-not-secret-key',
            'theme'     :   'light',
            'size'      :   'compact'
});
    }
</script>
<script src='https://www.google.com/recaptcha/api.js?onload=verifyCaptcha&render=explicit' async defer></script>



body
----
<form name='mailtest' method='post' action='/test/target.php'>
    <input type='text' name='name' value='joe bloggs' placeholder='Please enter your name' required />

    <!-- empty placeholder for re-captcha: targeted in javascript function verifyCaptcha -->
    <div id='grc'></div>

    <input type="submit" value="Submit form" />
</form>






/test/target.php (ie: the form target )
---------------------------------------
$google_secret='xxx-yyy-zzz-some-very-long-secret-key';
if( $_SERVER['REQUEST_METHOD']=='POST' ){

    $captcha=isset( $_POST['g-recaptcha-response'] ) && !empty( $_POST['g-recaptcha-response'] ) ? $_POST['g-recaptcha-response'] : false;
    if( !!$captcha===false ) die('empty captcha');

    $url="https://www.google.com/recaptcha/api/siteverify?secret=".$google_secret."&response=".trim( $captcha )."&remoteip=".$_SERVER['REMOTE_ADDR'];
    $response=json_decode( file_get_contents( $url ) );

    if( $response->success ){
        /* Everything ok - proceed with processing  */
    } else {
        /* Verification failed, abandon request */
    }

}

Upvotes: 1

Related Questions