Jump to content
Larry Ullman's Book Forums

Human Verification (Math) On A Form.

Recommended Posts

I wrote a script that generates two random numbers, adds them together, and stores the sum. On my form, I simply ask the question "what is $num1 + $num2?" If the user enters the correct answer when the form is submitted, the mail function sends the comments via email.


At first I stored the sum in the $_POST variable $_POST['sum'] in another variable, such as $sum. However, no matter what the user enters as an answer, it's marked incorrect on form submission because loading the form generates two new random numbers, and thus a new sum. I only got this to work correctly by storing the sum in a session, such as $_SESSION['sum']. Only then, does the answer submitted by the user verify with the sum of the original question.


Does this make sense? Am I coding this correctly by storing the answer to the original question in a session? Or is there a way to store the proper answer without using a session or a hidden input? In $_POST, for example.


Thanks, I'm really starting to understand PHP and writing my own scripts (that work) is very exciting.

Link to comment
Share on other sites

I understand roughly what your saying. But this may be easier to see your code (for me that is, it's late)


But to answer your question I would imagine that you would have to store it in a session if you are using the same page to validate the user's response. I did something similar with a captcha I wrote. :)

Link to comment
Share on other sites

Here's the rough code, without strong checks on the $_POST yet.


First part is the rough validation routine.


if (empty($_POST['answer'])){
       $errors['answer'] = 'Please answer the question';
       $flag = true;
   } elseif ($_SESSION['sum'] == $_POST['answer']){
       $answer = true;
       $flag = false;
   } else {
       $flag = true;
       $errors['answer'] = 'Incorrect answer.';


This is the HTML section with embedded PHP. I will put the random number section in a function eventually.


   $num1 = rand(10, 100);
   $num2 = rand(5, 50);
   $sum = $num1 + $num2;
   $_SESSION['sum'] = $sum;
   ?><Label for="question">What is <?php echo $num1 . ' + ' . $num2 . '?';
if (isset($errors['answer'])) {?> <span class="error"><?php echo $errors['answer'];?></span><?php }?></label><br>
   <input type="text" name="answer" id="answer"></input>

Link to comment
Share on other sites

I also got another verification to work... creating a captcha image with the gd library. In the example I learned from, the user's $_POST input is also matched against the image's value which is stored in a... session! I guess you need to store the original value in a session so it matches when the form is submitted, because if the math problem or captcha phrase is random, it will always change and not match the original value.


Would it be more secure to store the original value (in a session) with sha1 encryption, and then match the $_POST with the sha1 version of the original? Can you use sha1 on numbers too? (say, 15+20 = 35)

Link to comment
Share on other sites

Aside from the fact you've found it problematic storing the answer inside the form as a hidden input it also to a certain extent defeats the purpose of a turing/CAPTCHA test. If you want to ensure that only a human can submit your form then the answer needs to be stored in the session for security reasons.


As an example if you have a login system you wanted to force CAPTCHA on to prevent brute force logins and you stored the value in a hidden field it wouldn't take long to realised this and create a script that automatically scrapes the value and makes the appropriate submission.


While it would stop basic BOTs posting Viagra adds on your site it's certainly not best practice.


As for hashing the value in the session I personally don't see any real benefit in doing this as the values are transient - they alter on every single page load. But yes you can hash any string AFAIK.

Link to comment
Share on other sites

Thanks for your help, both of you. Everything is running smoothly when using sessions for the captcha and regular expressions for making sure no one uses my contact form as a spam relay. It was really fun drawing my own captcha with the gd library. I can't believe some of the things I'm doing after studying Larry's (and other author's) books for so long.

Link to comment
Share on other sites


  • Create New...