Reputation: 49
This just gets the random numbers. Then converts the int to a string. The string is used in the HTML.
$num1 = mt_rand(1, 9);
$num2 = mt_rand(1, 9);
$sum = $num1 + $num2;
$str1 = (string) $num1;
$str2 = (string) $num2;
This section just gets all the POST
information and variable declarations.
if (isset($_POST["submit"])) {
$name = $_POST['name'];
$email = $_POST['email'];
These are just declrations for variables.
$message = $_POST['message'];
$human = intval($_POST['human']);
$from = 'STEM and Buds Contact Form';
$to = '[email protected]';
$subject = $_POST['subject'];
$reason = $_POST['reason'];
This is where the code breaks. It always outputs Your anti-spam is incorrect
when it is correct. This is where the error occurs. The $num1
and $num2
variables are the two random values that I declared earlier and when those are summed and the user input is correct it should (theoretically) work.
<div class="form-group">
<label for="human" class="col-sm-2 control-label"><?php echo $str1 . " + " . $str2 . " = ?"; ?></label>
<div class="col-sm-10">
<input type="text" class="form-control" id="human" name="human" placeholder="Your Answer">
<?php echo "<p class='text-danger'>$errHuman</p>"; ?>
</div>
</div>
if ($human !== $num1 + $num2) {
$errHuman = 'Your anti-spam is incorrect';
}
Upvotes: 4
Views: 91
Reputation: 33813
To accomplish the math based captcha you need to use a session variable to store the answer and compare submitted answer against that session variable.
The following ought to help solve your issue - it is based around your original code snippets but does not have the full form with all the elements or variables but should give a clear idea how to proceed.
<?php
session_start();
$errHuman=false;
$num1 = mt_rand(1,9);
$num2 = mt_rand(1,9);
$sum = $num1 + $num2;
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['human'] ) && !empty( $_SESSION['math-captcha'] ) ){
$answer=filter_input( INPUT_POST, 'human', FILTER_SANITIZE_NUMBER_INT );
$errHuman = ( intval( $answer )==$_SESSION['math-captcha']->sum ) ? 'Congratulations' : 'Sorry - that is incorrect';
}
$_SESSION['math-captcha']=(object)array(
'num1' => $num1,
'num2' => $num2,
'sum' => (int)$sum
);
?>
<!DOCTYPE html>
<html>
<head>
<title>Math based captcha</title>
</head>
<body>
<form method='post'>
<!-- other form elements-->
<div class="form-group">
<label for="human" class="col-sm-2 control-label"><?php printf( '%d + %d=?', $num1, $num2 );?></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="human" placeholder="Your Answer">
<?php
if( $errHuman ){
printf('<p class="text-danger">%s</p>', $errHuman );
}
?>
</div>
</div>
<input type='submit' />
</form>
</body>
</html>
Upvotes: 0
Reputation: 3215
Every time a user sends the form with the correct human
value, the server receives the POST
request and generates new values for $num1
and $num2
. This is why your condition does not work.
You need to remember the operands and compare them against the values you showed to the user.
Simplest example (not safe against attack):
So, and this to your php file:
// init new random numbers
$num1New = mt_rand(1, 9);
$num2New = mt_rand(1, 9);
Add hidden values to your html form:
<input type="hidden" name="num1" value="<?php echo $num1New ?>">
<input type="hidden" name="num2" value="<?php echo $num2New ?>">
Extend receiving the variables:
$human = intval($_POST['human']);
$num1 = intval($_POST['num1']);
$num2 = intval($_POST['num2']);
In this case, you will compare the values which you displayed to the user.
Another solution would be to store the pair of the values in a database or user session or other storages.
Upvotes: 2