One of the duties of a webmaster is to prevent spam bots from submitting web forms. If spammers are not blocked, the data collected from the visitors will contaminated with spam and it's a real nuisance to clean out this data every so often. I have been researching ways to block spam on the web forms we have on our website and found a solution that works reasonably well.
The solution is based on Giorgos Tsiledakis' work, which he posted in Google Project and PHPClasses.org named formSpamBotBlocker (v0.3). I have greatly simplified the class and made the form values URL-friendly so that the class can be used to make Ajax calls. I've also made the public methods static so that the class can be used without instantiating an object.
// This script has been re-written from Giorgos Tsiledakis'
// formSpamBotBlocker v0.3. The new script removes the session
// checking feature. The form values are
// URL friendly for Ajax use, and the script has been simplified greatly.
//
// Edit the private variables for security and customization.
class SpamTrap
{
private static $version = "0.2"; // Release Version
// A hash key used to encrypt/decrypt a string.
private static $hashKey = "4SeCuRiTy";
private static $minSubmitTime = 3; // 3 Seconds.
private static $maxSubmitTime = 43200; // 24 Hours.
// Name of field where visitor info will be stored.
private static $visitorName = "_visitor";
// Honeypot Field - leave blank to disable.
// Do not use typical field names such as
// "honey", "trap" or "honeypot" in the name.
private static $honeypotName = "company";
public static function display()
{
$visitor = self::encrypt($_SERVER['HTTP_USER_AGENT']
. $_SERVER['REMOTE_ADDR']);
$data = "\n";
$name = "_" . substr($visitor, 0, 8);
$value = self::encrypt(time());
$data .= "\n";
if (!empty(self::$honeypotName)) {
$data .= "
\n";
}
return $data;
}
public static function encrypt($data)
{
// Base64 is not URL friendly, so translate non-URL friendly characters
// to URL-friendly characters.
return strtr(base64_encode($data . self::$hashKey), '+=/', '-_:');
}
public static function decrypt($data)
{
return preg_replace('/'.self::$hashKey.'$/', '',
base64_decode(strtr($data, '-_:', '+=/')));
}
public static function isSpam($data)
{
// Check visitor info (user agent and IP).
$visitorNew = $_SERVER['HTTP_USER_AGENT']
. $_SERVER['REMOTE_ADDR'];
$visitorOld = self::decrypt($data[self::$visitorName]);
if ($visitorNew != $visitorOld) {
return true;
}
// If honeypot tag is enabled, make sure it's empty.
if (!empty(self::$honeypotName)) {
if ($data[self::$honeypotName] != "") {
return true;
}
}
// Verify the form submit took at least $minSubmitTime;
$name = "_" . substr($data[self::$visitorName], 0, 8);
$elapsed = time() - self::decrypt($data[$name]);
if (($elapsed <= self::$minSubmitTime) ||
($elapsed > self::$maxSubmitTime)) {
return true;
}
return false;
}
public static function debug($data)
{
$message = "";
// Check visitor info (user agent and IP).
$visitorNew = $_SERVER['HTTP_USER_AGENT']
. $_SERVER['REMOTE_ADDR'];
$visitorOld = self::decrypt($data[self::$visitorName]);
if ($visitorNew != $visitorOld) {
$message .= "Different user agent or IP address. ";
}
// If honeypot tag is enabled, make sure it's empty.
if (!empty(self::$honeypotName)) {
if ($data[self::$honeypotName] != "") {
$message .= "Honeypot trapped. ";
}
}
// Verify the form submit took at least $minSubmitTime;
$name = "_" . substr($data[self::$visitorName], 0, 8);
$elapsed = time() - self::decrypt($data[$name]);
if (($elapsed <= self::$minSubmitTime) ||
($elapsed > self::$maxSubmitTime)) {
$message .= "Form submitted in {$elapsed} second(s).";
}
$message .= " Form submitted from "
. $_SERVER['REMOTE_ADDR'] . ".";
return $message;
}
}
References
- Form Spam Bot Blocker by Giorgos Tsiledakis.
Share this post
Leave a comment
All comments are moderated. Spammy and bot submitted comments are deleted. Please submit the comments that are helpful to others, and we'll approve your comments. A comment that includes outbound link will only be approved if the content is relevant to the topic, and has some value to our readers.
Comments (0)
No comment