FRANK DESIGN BLOG
// Stop spam without using CAPTCHA
Stop spam without using CAPTCHA
Verifying who (or in most cases, what) is filling in your online forms nowadays is essential. Whether this be to protect against brute force attacks or shield your clients from mindless, random sales pitches.
This means though that we have to resort to asking our visitors to repeat back two poorly rendered words. This, to me, is a very sad thing. And to be honest, it makes the internet seem primitive.
One of the most important things about how we go about verifying somebody is human is that we do it bearing in mind that many people have impairments. And it has to be said that CAPTCHAs are not very accessible. CAPTCHA solves hearing impairments by offering an extremely distorted audio recording,
which even I sometimes can't hear properly. And the issue still stands - we're having to ask.
A friendlier way
What we really need is a first line of defence that weeds out the obvious from the unknowns, and for this we can use a use-by date. 
As it's an automated process, spam bots will generally submit a form ridiculously fast, so timing how long your form takes to get filled in is a good starting point. It's easy to implement and has the advantages of:
- Having no need for your visitor to do anything (apart from fill out the form)
- Being extremely accessible as the visitor doesn't have to read, type or listen to anything
Of course, a bot can be programmed to vary the time it submits a form, and we'll come to this in a later post, but you'll be surprised just how effective this method is by itself.
Click here to go to a demonstration using PHP and its predefined variable $_SESSION.A similar technique is just as easy in any other language.
session_start();
DEFINE('MIN_SECONDS', 5); // Minimum time the form should take to complete
$timenow = time();
$process = false;
if (isset($_SESSION['timecheck']['landtime']) && $_POST) {
$landtime = $_SESSION['timecheck']['landtime'];
// Check the amount of time it took
if (($landtime + MIN_SECONDS) < $timenow) {
// Passes time check
$process = true;
} else {
// Probably spam
$process = false;
}
// Reset the timer
$_SESSION['timecheck']['landtime'] = $timenow;
} else {
// This is the first page request so set the session variable to
// the current time
$_SESSION['timecheck']['landtime'] = $timenow;
}
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Form time check example</title>
<link href="assets/css/bootstrap.css" media="screen" rel="stylesheet" type="text/css">
<link href="assets/css/bootstrap-responsive.css" media="screen" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<div class="row">
<div class="span12">
<h1>Example</h1>
<h2>Using sessions to stop spam</h2>
<p>The example below will not let you submit the form if it is within 5 seconds.</p>
<?php
if (isset($_SESSION['timecheck']['landtime']) && $_POST) {
if ($process === true) {
$message = 'Thank you for submitting the form.';
$alerttype = 'alert-success';
} else if ($process === false) {
$message = 'Sorry you submitted the form too quickly.';
$alerttype = 'alert-error';
}
echo '<div class="alert '.$alerttype.'">';
echo $message;
echo '</div>';
}
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="nameInput">Your name</label>
<div class="controls">
<input type="text" id="nameInput" name="name" placeholder="Your name">
</div>
</div>
<div class="control-group">
<label class="control-label" for="emailaddressInput">Your email address</label>
<div class="controls">
<input type="text" id="emailaddressInput" name="emailaddress" placeholder="Your email address">
</div>
</div>
<div class="control-group">
<label class="control-label" for="messageTextarea">Your message</label>
<div class="controls">
<textarea rows="5" id="messageTextarea" name="message" placeholder="Your message"></textarea>
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Coming soon
In the next post I will demonstrate an idea that can accompany the above method using mail headers to allow the form to get sent but be flagged as spam.