Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Some help with reCAPTCHA

Options
  • 07-09-2011 4:24pm
    #1
    Registered Users Posts: 1,484 ✭✭✭


    Hi, i'm very inexperienced when it comes to php and i'm trying to secure a web-form i've created. I think i'm almost done but i don't seem to be able to implement CAPTCHA properly. The widget shows up in the form but i'm not sure if it is validating. I know i'm missing a couple of vital bits of code but i don't know what they are.

    I want to my form to be validated by my own code first, then if the input is validated i want to check if the CAPTCHA input is correct. Can someone help me out please?
    <div id="contact-form" class="clearfix">
    					<h1>Get In Touch!</h1>
    					<h2>
    						Please provide as much information as possible for me to help you with your enquiry
    					</h2>
    					<?php  
    						//init variables  
    						$cf = array();  
    						$sr = false;  
    							
    						if(isset($_SESSION['cf_returndata'])){  
    								$cf = $_SESSION['cf_returndata'];  
    								$sr = true;  
    						}  
    					?>  
    					<ul id="errors" class="<?php echo ($sr && !$cf['form_ok']) ? 'visible' : ''; ?>">  
    						<li id="info">There were some problems with your form submission:</li>  
    						<?php  
    						if(isset($cf['errors']) && count($cf['errors']) > 0) :  
    								foreach($cf['errors'] as $error) :  
    						?>  
    						<li><?php echo $error ?></li>  
    						<?php  
    								endforeach;  
    						endif;  
    						?>  
    					</ul>  
    					<p id="success" class="<?php echo ($sr && $cf['form_ok']) ? 'visible' : ''; ?>">Thanks for your message! We will get back to you ASAP!</p> 
    					<form method="post" action="process.php">
    						<label for="name">Name: <span class="required">*</span></label>  
    						<input type="text" id="name" name="name" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['name'] : '' ?>" placeholder="John Doe" required="required" autofocus="autofocus" />  
    								
    						<label for="email">Email Address: <span class="required">*</span></label>  
    						<input type="email" id="email" name="email" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['email'] : '' ?>" placeholder="johndoe@example.com" required="required" />  
    		
    						<label for="message">Message: <span class="required">*</span></label>  
    						<textarea id="message" name="message" placeholder="Your message must be greater than 20 charcters" required="required" data-minlength="20"><?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['message'] : '' ?></textarea>  
    							
    						<span id="loading"></span>  
    						
    						<!--recaptcha-->
    						<?php
    							require_once('recaptchalib.php');
    							$publickey = "6Leb48cSAAAAALi84SNJgUgrgKNbfstSQu1Y1GJj"; 
    							echo recaptcha_get_html($publickey);
    						?>
    						
    						<input type="submit" value="Send!" id="submit-button" />  
    						<p id="req-field-desc"><span class="required">*</span> indicates a required field</p> 
    					</form>
    				<?php unset($_SESSION['cf_returndata']); ?>  	
    				</div>
    

    [PHP]
    <?php
    if( isset($_POST) ){

    //security functions

    function cleanInput($input) {

    $search = array(
    '@&lt;script[^>]*?>.*?</script>@si', // Strip out javascript
    '@&lt;[\/\!]*?[^<>]*?>@si', // Strip out HTML tags
    '@&lt;style[^>]*?>.*?</style>@siU', // Strip style tags properly
    '@&lt;![\s\S]*?--[ \t\n\r]*>@' // Strip multi-line comments
    );

    $output = preg_replace($search, '', $input);
    return $output;
    }


    function sanitize($input) {
    if (is_array($input)) {
    foreach($input as $var=>$val) {
    $output[$var] = sanitize($val);
    }
    }
    else {
    if (get_magic_quotes_gpc()) {
    $input = stripslashes($input);
    }
    $input = cleanInput($input);
    $output = mysql_real_escape_string($input);
    }
    return $output;
    }


    //form validation vars
    $formok = true;
    $errors = array();

    //sumbission data
    $ipaddress = $_SERVER;
    $date = date('d/m/Y');
    $time = date('H:i:s');

    //form data
    $name = sanitize($_POST);
    $email = sanitize($_POST);
    $message = sanitize($_POST);

    //form validation to go here....

    //validate name is not empty
    if(empty($name)){
    $formok = false;
    $errors[] = "You have not entered a name";
    }

    //validate email address is not empty
    if(empty($email)){
    $formok = false;
    $errors[] = "You have not entered an email address";
    //validate email address is valid
    }elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $formok = false;
    $errors[] = "You have not entered a valid email address";
    }

    //validate message is not empty
    if(empty($message)){
    $formok = false;
    $errors[] = "You have not entered a message";
    }
    //validate message is greater than 20 charcters
    elseif(strlen($message) < 20){
    $formok = false;
    $errors[] = "Your message must be greater than 20 characters";
    }

    // captcha
    require_once('recaptchalib.php');
    $privatekey = "6Leb48cSAAAAALzy2VHGtkGniE-8o5KJcoQkyjA7";
    $resp = recaptcha_check_answer ($privatekey,
    $_SERVER["REMOTE_ADDR"],
    $_POST["recaptcha_challenge_field"],
    $_POST["recaptcha_response_field"]);

    if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
    $formok = false;
    $errors[] = "captcha error";
    }

    //send email if all is ok
    if($formok){
    $headers = "From: {$email}" . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

    $emailbody = "<p>You have recieved a new message from the enquiries form on your website.</p>
    <p><strong>Name: </strong> {$name} </p>
    <p><strong>Email Address: </strong> {$email} </p>
    <p><strong>Message: </strong> {$message} </p>
    <p>This message was sent from the IP Address: {$ipaddress} on {$date} at {$time}</p>";

    mail("xxxxxxx@gmail.com","New Enquiry",$emailbody,$headers);

    }

    //what we need to return back to our form
    $returndata = array(
    'posted_form_data' => array(
    'name' => $name,
    'email' => $email,
    'message' => $message
    ),
    'form_ok' => $formok,
    'errors' => $errors
    );

    //if this is not an ajax request
    if(empty($_SERVER) && strtolower($_SERVER) !== 'xmlhttprequest'){

    //set session variables
    session_start();
    $_SESSION = $returndata;

    //redirect back to form
    header('location: ' . $_SERVER);

    }

    }

    [/PHP]

    EDIT: The captcha validation seems to be working in so far as it will not send an email if the captcha input is incorrect. But it will not report an error to the user, so it will appear to the user that the message has been successfully sent.

    I have tried to make it output a simple error message in the code above in line 91 of the second section of code but it's not working for me.


Comments

  • Registered Users Posts: 15,065 ✭✭✭✭Malice


    At risk of stating the obvious have you read through this? I don't know much PHP so the only mistake I can spot in the above code is that you've spelt "received" wrong :p.


  • Registered Users Posts: 1,484 ✭✭✭gnolan


    Malice wrote: »
    At risk of stating the obvious have you read through this? I don't know much PHP so the only mistake I can spot in the above code is that you've spelt "received" wrong :p.

    Also spelt characters wrong! Yep, I've read that but still can't figure it out. It all makes a certain amount of sense to me but i'm having trouble implementing it in my own code.


  • Registered Users Posts: 15,065 ✭✭✭✭Malice


    Just to be even pickier:
    elseif(strlen($message) < 20){  
            $formok = false;  
            $errors[] = "Your message must be greater than 20 characters";  
        }
    
    is supposed to ensure that the message is greater than 20 characters but if a user enters exactly 20 chars then the check will succeed. You might want to do
    elseif(strlen($message) <= 20){
    
    or
    elseif(strlen($message) < 21){
    
    I've worked with some very dedicated testers so I always watch statements like that to make sure they're valid!
    gnolan wrote:
    it will not report an error to the user
    Is there anything at all in the $returndata object or is it just the error messages that are missing?


  • Registered Users Posts: 1,484 ✭✭✭gnolan


    Didn't notice the stringlength bit there, thanks.

    As far as i can tell the $returndata object is empty - my form is not repopulated with my original inputs.

    My error messages work fine for the name, email and message inputs but it is the recaptcha error that doesn't show. In fact, if i input the incorrect words for recaptcha i get a success message but no email is actually sent.

    I have to apologize. I've just changed my code because it wasn't working properly, i had been using a cached version i think.

    This is the code i have now with the same problems. Sorry again. Just to be clear, slightly different code, same problems.

    [PHP]
    <?php

    require_once('recaptchalib.php');
    $privatekey = "6LfZ5ccSAAAAAPkARubACmc3iuvz_LEXr0AikwFX";
    $resp = recaptcha_check_answer ($privatekey,
    $_SERVER["REMOTE_ADDR"],
    $_POST["recaptcha_challenge_field"],
    $_POST["recaptcha_response_field"]);
    if (!$resp->is_valid) {
    // What happens when the CAPTCHA was entered incorrectly
    die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." .
    "(reCAPTCHA said: " . $resp->error . ")");
    } else {
    // Your code here to handle a successful verification
    }


    if( isset($_POST) ){

    //security functions

    function cleanInput($input) {

    $search = array(
    '@&lt;script[^>]*?>.*?</script>@si', // Strip out javascript
    '@&lt;[\/\!]*?[^<>]*?>@si', // Strip out HTML tags
    '@&lt;style[^>]*?>.*?</style>@siU', // Strip style tags properly
    '@&lt;![\s\S]*?--[ \t\n\r]*>@' // Strip multi-line comments
    );

    $output = preg_replace($search, '', $input);
    return $output;
    }


    function sanitize($input) {
    if (is_array($input)) {
    foreach($input as $var=>$val) {
    $output[$var] = sanitize($val);
    }
    }
    else {
    if (get_magic_quotes_gpc()) {
    $input = stripslashes($input);
    }
    $input = cleanInput($input);
    $output = mysql_real_escape_string($input);
    }
    return $output;
    }


    //form validation vars
    $formok = true;
    $errors = array();

    //sumbission data
    $ipaddress = $_SERVER;
    $date = date('d/m/Y');
    $time = date('H:i:s');

    //form data
    $name = sanitize($_POST);
    $email = sanitize($_POST);
    $message = sanitize($_POST);

    //form validation to go here....

    //validate name is not empty
    if(empty($name)){
    $formok = false;
    $errors[] = "You have not entered a name";
    }

    //validate email address is not empty
    if(empty($email)){
    $formok = false;
    $errors[] = "You have not entered an email address";
    //validate email address is valid
    }elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $formok = false;
    $errors[] = "You have not entered a valid email address";
    }

    //validate message is not empty
    if(empty($message)){
    $formok = false;
    $errors[] = "You have not entered a message";
    }
    //validate message is greater than 20 charcters
    elseif(strlen($message) < 21){
    $formok = false;
    $errors[] = "Your message must be greater than 20 characters";
    }

    //send email if all is ok
    if($formok){
    $headers = "From: {$email}" . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

    $emailbody = "<p>You have recieved a new message from the enquiries form on your website.</p>
    <p><strong>Name: </strong> {$name} </p>
    <p><strong>Email Address: </strong> {$email} </p>
    <p><strong>Message: </strong> {$message} </p>
    <p>This message was sent from the IP Address: {$ipaddress} on {$date} at {$time}</p>";

    mail("garethdn@gmail.com","New Enquiry",$emailbody,$headers);

    }

    //what we need to return back to our form
    $returndata = array(
    'posted_form_data' => array(
    'name' => $name,
    'email' => $email,
    'message' => $message
    ),
    'form_ok' => $formok,
    'errors' => $errors
    );

    //if this is not an ajax request
    if(empty($_SERVER) && strtolower($_SERVER) !== 'xmlhttprequest'){

    //set session variables
    session_start();
    $_SESSION = $returndata;

    //redirect back to form
    header('location: ' . $_SERVER);

    }

    }

    [/PHP]

    I've basically moved the recaptcha stuff right to the top. I don't know where to go from here.


  • Registered Users Posts: 16,413 ✭✭✭✭Trojan


    I almost never code contact forms, even complex ones, manually these days - there are far too many better options out there that get it done in 1/10th the time. If PHP isn't your strong suit, are you sure you want to build this yourself? Check out these options:

    http://green-beast.com/gbcf-v3/
    http://www.gravityforms.com/
    http://wordpress.org/extend/plugins/contact-form-7/
    http://wufoo.com/
    http://www.formstack.com/

    (Of course if you're doing this to learn PHP/reCAPTCHA, please ignore and have a nice day :))


  • Advertisement
  • Registered Users Posts: 1,484 ✭✭✭gnolan


    Thanks for that Trojan. I've since been looking around for alternative ways to avoid spam bots and found an interesting one which i think i'll try.

    It involves adding an extra input in the form which is given the property "display: none" in the stylesheet. The idea is that spam bots will automatically fill out this input as it will be trawling through the raw html, and the user won't be able to fill it out because it will be hidden in the browser.

    In my process.php file i then check to see that this field is empty. If so, the message is sent, if not the message is not sent.

    Does this seem like a good anti-bot solution?


Advertisement