Today web programmers have big problems with spam comments. There are a lot of tutorials about captchas and how to implement them, so I will not cover it here (I can do it f next tutorial if you wish). Anyway, I will show you some other methods that are good. Note that none of them is not 100% secure. Methods that I will show you
Those are not their official names, but I don’t know how else to call them. So let me explain each of them.
First we have Referer check. That method checks referrer. When someone comes to your site and he want to submit a comment or any other thing through you form, he first opens that forms page. When he writes what he wants, he hits submit button and form is submitted. When that happens, browser ads new entry to header and that is Referrer. It’s value is form URL. So if you wanna be sure that user submitted page through your form, just check if URL of the form is same as Referer URL. This can be easily passed by manually adding that entry to headers, but most of spamers don’t remember that this could be used.
Next we have Blacklist check. It’s nothing special. We just have database with IP-s that are know as spam IP-s, and we just check if visitor IP is same as one in our database. This could be avoided using proxy servers.
Last we have Random string check. This method is most secure of those 3. It forces user to first visit your forms page, and them submit his comment. It just adds a hidden field in your form with some random string. That string is stored in session and when user submits form, we check if code from his session is same as one in the form.
I’ll show you a simple form where I’ve implemented all of these checks. First we have our form file. That file is our base and we include our php file into it. Basically it’s just html with form and on top of it is some PHP code that I will explain. So this is our form.php (or you can call it index.php if you’d like
).
< ?php
session_start();
require_once 'db.php';
if (!isset($_POST['submit']))
$_SESSION['randomString'] = uniqid();
else {
require_once 'check.php';
if (!$rez['error']) {
require_once 'submit.php';
}
}
?>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Antispam form</title>
<style type="text/css">
body {
background-color: #f0f0f0;
}
#wrapper {
margin: 100px auto;
width: 310px;
}
fieldset {
margin-top: 10px;
background: #fff;
border: 1px solid #c8c8c8;
}
legend {
background: #fff;
border-top: 1px solid #c8c8c8;
border-right: 1px solid #c8c8c8;
border-left: 1px solid #c8c8c8;
font-size: 1.2em;
padding: 0px 7px;
}
label {
display: inline-block;
width: 50px;
}
#email {
width: 248px;
}
#text {
width: 248px;
height: 70px;
}
.success {
width: 298px;
background: #a5e283;
border: #337f09 1px solid;
padding: 5px;
}
.error {
width: 298px;
background: #ea7e7e;
border: #a71010 1px solid;
padding: 5px;
}
</style>
</head>
<body>
<div id="wrapper">
< ?php if (isset($rez['msg'])) : ?>
<div class="<?php echo ($rez['error']) ? 'error' : 'success'; ?>">
< ?php echo $rez['msg']; ?>
</div>
< ?php endif; ?>
<form action="" method="post">
<fieldset>
<legend>Demo form</legend>
<span style="font-size: 0.9em;">This form will be used for demonstration of antispam measures.</span>
<p>
<label for="email">E-Mail:</label>
<input type="text" name="email" id="email" value="" />
</p>
<p>
<label for="text" style="float: left; clear: both; margin-right: 3px;">Text:</label>
<textarea name="text" id="text"></textarea>
</p>
<p>
<input type="hidden" value="<?php echo $_SESSION['randomString']; ?/>" name="randomString" />
<input type="submit" name="submit" style="float: right; clear: both; margin-right: 3px;" value="Submit" />
</p>
</fieldset>
</form>
</div>
</body>
</html>
Interesting parts are on top of the page, and in the middle we just have some simple if statement to see if we have message. If we do, check what type and echo appropriate css style.
On top of our page, we start session and require our database connection. After that we check if request is POST. If it's not, we generate random string that will be echoed in our form as hidden field. If request is POST, we are including file to check users input and if we do not have errors we submit our form.
This is db.php.
< ?php
$con = mysql_connect('host', 'username', 'password');
mysql_select_db('database');
Replace host, username etc. with your details.
Now we have check.php.
< ?php
$rez['error'] = false;
/**
* Part for checking random string.
*/
while (true) {
if (!isset($_POST['randomString'])) {
$rez['error'] = true;
$rez['msg'] = 'Your unique ID is not presented.';
break;
}
if ($_SESSION['randomString'] !== $_POST['randomString']) {
$rez['error'] = true;
$rez['msg'] = 'Your unique ID and forms unique ID are not the same.';
break;
}
$_SESSION['hash'] = null;
break;
}
/**
* Part for checking referer.
*/
while (true) {
if (!isset($_SERVER['HTTP_REFERER']) || strpos($_SERVER['HTTP_REFERER'], 'tutoriali') === false) {
$rez['error'] = true;
$rez['msg'] = 'Referer not found. Please use our form to submit your comment.';
break;
}
break;
}
/**
* Part for checking black listed IP-s.
*/
while (true) {
$sql = "SELECT *"
. " FROM `blacklist`"
. " WHERE `ip` = '" . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . "'";
if (($mysqlRez = mysql_query($sql)) === false) {
$rez['error'] = true;
$rez['msg'] = 'Failed to execute query.';
break;
}
if (mysql_num_rows($mysqlRez) > 0) {
$rez['error'] = true;
$rez['msg'] = 'Your IP is on our blacklist.';
break;
}
break;
}
I think you know what's going on here. We have a variable $rez that is an array and will have a key error that will contain info about error (true or false). And we will have key msg that will have text message. We have 3 while loops that we use for checking. I usually use while loops when I would have nested if statements. If I come across and error, I just break loop and assign to some variable true if we have error. At the end of our loop we ad an other break to prevent infinite loop (if we ad condition like that). I think you can all understand what's going on here since those are simple if statements.
You can download source code here. I've also included test.php and table.sql. First file has some CURL test for referers and SQL file has info about blacklist table. You will insert your blacklisted IP-s there.
I don’t care other but for me your articles is useful to me …
Thank you……
Well, what ever was made by man could be easily hacked one way or an other. Your forms will never be 100% safe.
I just wanted to give some basic ideas how to fight spam.
Mind this, your work around are the basics. I once thought that those are enough.
But until some bot spamming into my site with a very advanced technology, i’ve been trembled by the technique of hacking.
Http referer is really easy to be faked. How many anonymous ip you will blacklist? The bot can easily change into another ip in a minute or less.
And the random string which is attached into html form is can be predicted no matter how advance you will hide or obfuscate it.
They are way too professional for only this.
Even they can bypass most of advanced captcha that ever made.
[...] Then we do some checking. If you are wondering why we use while loop to check our data, read this tutorial (at the bottom of the page). First 3 checks validate if user has entered all required [...]