Jump to content

Custom PHP CAPTCHA


BuildMyWeb

Recommended Posts

ive written a php function that displays a random equation.  if the correct answer is not provided, the submission fails.  the equation is like so:

 

[ random digit or text number ]  [ randomly selects +,-,x ]  [ random digit or text number ]= ?

 

so you might see:

8+2=?, or seven - 4 = ?, etc

 

ive tested this manually and it seems to work beautifully.  i cannot get around answering the CAPTCHA correctly.  yet something or someone IS posting spam despite this CAPTCHA.  so my question is, are the programs out there that can solve this problem?

 

 

here is my form:

<form action="scripts/handler_post.php" method="post" id="gb_form">
                	<h3>Leave us a comment:</h3><br />
                    <div id="form_msg"><?php echo $msg; ?></div>
                	<input type="text" name="name" value="Your Name" />
                    <textarea name="message">Your Message</textarea>
                    
                    <?php include('includes/bmw_captcha.php'); ?> 
                    <div style="color:red; font-size:90%;">*What does <?php echo $array_num1[1] . " " . $array_calculation[0] . " " . $array_num2[1] . " = "; ?>	
                    <input type='text' maxlength='2' name='captcha' style="color:#640513; width:25px;" />?</div>
                    <div><span style="font:italic 90% Arial; color:#666;">(For security purposes, please answer this CAPTCHA problem.)</span></div>
                    <input type="hidden" name="captcha_answer" value="<?php echo $array_calculation[1]; ?>" />
            
                	<input type="submit" name="submit_button" value="Post" />
                </form>

 

here is the script that handles the form:

// submitted values
$name		= clean_string( $_POST['name'] );
$message	= clean_string( $_POST['message'] );
$captcha 	= clean_string( $_POST['captcha'] );
$captcha_ans= clean_string( $_POST['captcha_answer'] );

// check if name var is empty or contains digits
if( empty($name) || (strcspn( $name, '0123456789' ) != strlen( $name )) ) 
{ header( 'Location: /guestbook.php?msg=n' ); }

else if( empty($message) )
{ header( 'Location: /guestbook.php?msg=m' ); }

else if( empty($captcha) || $captcha != $captcha_ans )
{ header( 'Location: /guestbook.php?msg=cap' ); }

else 
{
	$query = "
			INSERT INTO $table_posts ( id, name, message, timestamp ) 
			VALUES( 0, \"$name\", \"$message\", now() )
	";

	$result = $db_connect->query( $query ); // execute the query

	if( $result )
	{		
		header('Location: ../guestbook.php?msg=1');
	}

	else
		header('Location: ../guestbook.php?msg=2');
}

Link to comment
Share on other sites

Well, your captha is

yet something or someone IS posting spam despite this CAPTCHA.

 

What do you mean "despite" the captcha? Have you verified that the responses are not entering the correct response to the captcha and are getting processed anyway or are you saying that these submissions are entering the captcha and have content you don't want.

 

If the responses are not entering the correct captcha response  you need to look for loopholes in the system. For example, I see that you are having the captcha response AND the answer included in the POST data. That's kinda worthless since you cannot control what is subitted in the POST data. Even if you have a hidden field with a value you set, it is child's play to modify that value when the form is submitted. It would be very easy for someone to create a custom form submission that would bypass that validation by simply submitting the same values for those two fields. You should NOT include the answer in the form - at least not directly. you could store it in a session value, but there are some problems with that. Or you could store a hash of the solution in the form. Then compare a hash of the answer against the answer value.

 

But, if the answers are getting submitted it could be a human that is entering the captcha and there is no good way to prevent that except through an approval process, blocking IPs, etc. etc. Or it could be a script that is reading the form to calculate the response. Either someone built one specifically for your site or it is one that has some "intelligence" built in to deduce what you are doing.

Link to comment
Share on other sites

Have you verified that the responses are not entering the correct response to the captcha...

no i have not.  that is a good point.

 

You should NOT include the answer in the form - at least not directly. you could store it in a session value

this was offered to me elsewhere and so ive now put the captcha_answer in a SESSION variable.  but youre saying there could be problems with that?  how so?

 

 

Link to comment
Share on other sites

You should NOT include the answer in the form - at least not directly. you could store it in a session value

this was offered to me elsewhere and so ive now put the captcha_answer in a SESSION variable.  but youre saying there could be problems with that?  how so?

 

The main problem that comes to mind is concurrency. A user could have two windows open for your form at tone time. However, only the last value would have been saved to session. So, if the user submits the first page their response would fail. I'd actually go with using a hash.

 

When creating the form determine the answer. Create a hash of that answer and populate that into a hidden field. Then when the for is submitted, take the response and hash it in the same was as you did for the answer. If the two are the same you pass the validation.

Link to comment
Share on other sites

Or it could be that the bots are indeed solving the rather trivial maths questions, it's not as if computers have a hard time doing maths.

 

As for the concurrency problem: I reckon you are using some method to generate the CAPTCHA, and set its name/value. By creating a unique ID for each load of the CAPTCHA, then you can use this ID as an index when saving the result in the session. Use the value in the form, and you know what answer is the correct one regardless of how many copies you have open at the same time.

I'd also recommend adding a timestamp to the ID, so that you can clear it out once the time limit has passed. Will prevent someone from performing a DOS attack, by spamming the session storage.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.