Jump to content

stop blog comment spam


foevah

Recommended Posts

Hi everyone I am now experiencing a menace that is adding comments to my blog entries for no reason. I have searched this forum for answers and I have also read this page: http://www.sitepoint.com/article/stop-comment-spam

 

I would like to try and install captcha into my comment form and if possible I would like to get the IP of this pesky user and BAN them from using my comments form forever!

 

I am not sure how to install captcha or how to get the users IP and then to ban the IP.

 

Please can someone help me stop this spammer and help me install a solution!

 

This is the code for my comments page (comment form is at the end):

<?php

function showinweb($val) {

    $val = nl2br($val);
//return returns the value and ends execution of function, so any line below it is ignored	
    return($val);

while($row = mysql_fetch_array($result)) {

    $date = date("l F d Y", $row['timestamp']);
    $title = stripslashes($row['title']);
    $entry = stripslashes($row['entry']);
    $image = stripslashes($row['image']);
                     ?>
                <?php $sql = "SELECT *, DATE_FORMAT(timestamp, '%a.%b.%y') as dateAdded FROM php_blog WHERE id='$id' ORDER BY timestamp"; 
$result = mysql_query ($sql) or print ("Can't select comments from table php_blog_comments.<br />" . $sql . "<br />" . mysql_error()); 
while($row = mysql_fetch_assoc($result)) {

	echo "<div class='box1'>";
	echo "<p class='blogtitle'> <span class='blogtit'>".showinweb($row['title'])."</span></p><br />";
	echo "<br /><br />".smiley(showinweb($row['entry'])); 
        echo "<img id='thisimage$i' onmouseover='showdiv(this.id);' onmouseout ='hidediv();' src='../entry/blog_images/".showinweb($row['image'])."' alt='' /> ";
         echo "<br />".showinweb($row['dateAdded']);
	 echo "</div>";
}  
?>
             <?php
             }
         }
         else {
            echo "<p><strong>" . $title . "</strong></p>";

            printf("<form method=\"post\" action=\"journal.php?id=%s\"><p><strong><label for=\"username\">Username:</label></strong><br /><input type=\"text\" name=\"username\" id=\"username\" /></p><p><strong><p><input type=\"submit\" name=\"submit\" id=\"submit\" value=\"submit\" /></p></form>",$id);
            print "<hr /><br /><br />";
        }
    }
    else { ?>

                <?php $sql = "SELECT *, DATE_FORMAT(timestamp, '%a.%b.%y') as dateAdded FROM php_blog WHERE id='$id' ORDER BY timestamp"; 
$result = mysql_query ($sql) or print ("Can't select comments from table php_blog_comments.<br />" . $sql . "<br />" . mysql_error()); 
while($row = mysql_fetch_assoc($result)) {

	echo "<div class='box1'>";
	echo "<p class='blogtitle'> <span class='blogtit'>".showinweb($row['title'])."</span></p><br />";
	echo "<br /><br />".smiley(showinweb($row['entry'])); 
        echo "<img id='thisimage$i' onmouseover='showdiv(this.id);' onmouseout ='hidediv();' src='../entry/blog_images/".showinweb($row['image'])."' alt='' /> ";
        echo "<br />".showinweb($row['dateAdded']); 
    	echo "</div>";


}   
?>

        <?php
    }
}
$commenttimestamp = strtotime("now");

$sql = "SELECT * FROM php_blog_comments WHERE entry='$id' ORDER BY timestamp";
$result = mysql_query ($sql) or print ("Can't select comments from table php_blog_comments.<br />" . $sql . "<br />" . mysql_error());
while($row = mysql_fetch_array($result)) {
    $timestamp = date("l F d Y", $row['timestamp']);
    echo "<div class='box1'>";
    echo "<br /><br />".smiley(showinweb($row['comment'])); 
printf("<p>Comment by <a href=\"%s\">%s</a> @ %s</p>", stripslashes($row['url']), stripslashes($row['name']), $timestamp);
echo "</div>";
}
?>

<form method="post" action="../process.php">

<p><input type="hidden" name="entry" id="entry" value="<?php echo $id; ?>" />
<input type="hidden" name="timestamp" id="timestamp" value="<?php echo $commenttimestamp; ?>">

<strong><label for="name">Name:</label></strong> <input type="text" name="name" id="name" size="25" /><br />
<strong><label for="email">E-mail:</label></strong> <input type="text" name="email" id="email" size="25" /><br />
<strong><label for="url">URL:</label></strong> <input type="text" name="url" id="url" size="25" value="http://" /><br />
<strong><label for="comment">Comment:</label></strong><br />
<textarea cols="25" rows="5" name="comment" id="comment"></textarea></p>

<p><input type="submit" name="submit_comment" id="submit_comment" value="Add Comment" /></p>
</form>

 

 

Link to comment
Share on other sites

Another good approach is to make all comment require admin approval.

 

You can also use a technique I think I invented but probably didn't. Basically, you make the variable names for the forms random, with the one for message always derived from the one for the name. Don't write these files to the html, write these files as javascript that rewrites itself.

 

So, instead of being able to spam the form with the same values, he has to convert some form-creating javascript to the correct input names, then use those to spam. This only protects against scripted-bots, doesn't protect against macro's or a live person.

Link to comment
Share on other sites

Good captcha's will stop most automated tasks. I've written a simple one for a script of mine, but u can customize it as u want:

 

<?php
header("Content-type: image/jpg");
session_start();

$width = 100;
$height = 30;
$nrChars = 5;
$numbers = '123456789';

for($i=0; $i<$nrChars; $i++){
$randomChar = rand(0, strlen($numbers)-1);
$text .= $numbers[$randomChar];
}
$_SESSION['captcha'] = sha1($text);

$image = imagecreate($width, $height);
$background = imagecolorallocate($image, 0, 50, 150);

$gridColor = imagecolorallocate($image, 0, 0, 250);
for($i=0; $i<50; $i++){
imageline($image, 10*$i, 0, 10*$i, $height, $gridColor);
}
for($i=0; $i<3; $i++){
imageline($image, 0, 10*$i, $width, 10*$i, $gridColor);
}

for($i=0; $i<20; $i++){
$linesColor = imagecolorallocate($image, $i*4, 0, $i*2);
$x1 = rand(0, $width);
$x2 = rand(0, $width);
$y1 = rand(0, $height);
$y1 = rand(0, $height);
imageline($image, $x1, $y1, $x2, $y2, $linesColor);
}

$textColor = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 10, 30, 7, $text, $textColor);

imagepng($image);
imagedestroy($image);
?>

 

Save it as 'captcha.php' and in the page where u want to show it, just wrap it in <img> tag:

 

<img src="captcha.php" />

 

And validate the user input with the sha1 encrypted $_SESSION['captcha'].

 

As for the IP addresses, u can log each input in the form in a text file or db.

 

$ip = GetHostByName($REMOTE_ADDR);
$handle = fopen('logs.txt', 'w');
fwrite($handle, $ip);
fclose($handle);

 

Hope i gave u some good code and help.

Link to comment
Share on other sites

Another good approach is to make all comment require admin approval.

How can I make comments get admin approval?

You can also use a technique I think I invented but probably didn't. Basically, you make the variable names for the forms random, with the one for message always derived from the one for the name. Don't write these files to the html, write these files as javascript that rewrites itself.

 

So, instead of being able to spam the form with the same values, he has to convert some form-creating javascript to the correct input names, then use those to spam. This only protects against scripted-bots, doesn't protect against macro's or a live person.

This JS way sounds complicated. Id like to learn it but I havent got a clue how to do it..

 

Hi GuiltyGear!

I have made the new page captcha.php with the PHP you have provided and I have added <img src="captcha.php" /> just about the comment submit button. I am a bit stuck on how to / where to add this: sha1 encrypted $_SESSION['captcha'] ? ?

Every time I refresh the page a new image with different numbers appear so its nearly working :)

 

 

If I add the code below at the top of the comments page will it work (is it that simple)?

$ip = GetHostByName($REMOTE_ADDR);
$handle = fopen('logs.txt', 'w');
fwrite($handle, $ip);
fclose($handle);

 

 

 

 

Link to comment
Share on other sites

Everytime the captcha is refreshed, its containing text is registered to $_SESSION['captcha'] and is encrypted. U need to validate the input got from the input text with the session.

 

<?php
if(isset($_POST['captchacode'])){
    if(sha1($_POST['captchacode']) == $_SESSION['captcha']){
         //add the comment to db or whatever
    } else{
        echo "The code u provided is invalid. Try again.";
    }
}
?>

 

As for the ip to logs thing, probably u'll need to write to the file after the user provides a valid captcha code and the comment is posted. Write also the date() and what he/she wrote also with the ip.

Link to comment
Share on other sites

This is how my form looks.. I think I have done it wrong:

 

<form method="post" action="../process.php">

<p><input type="hidden" name="entry" id="entry" value="<?php echo $id; ?>" />
<input type="hidden" name="timestamp" id="timestamp" value="<?php echo $commenttimestamp; ?>">
<strong><label for="name">Name:</label></strong> <input type="text" name="name" id="name" size="25" /><br />
<strong><label for="email">E-mail:</label></strong> <input type="text" name="email" id="email" size="25" /><br />
<strong><label for="url">URL:</label></strong> <input type="text" name="url" id="url" size="25" value="http://" /><br />
<strong><label for="comment">Comment:</label></strong><br />
<textarea cols="25" rows="5" name="comment" id="comment"></textarea></p>
<img src="captcha.php" />
<strong><label for="captchacode">Code:</label></strong> <input type="text" name="captchacode" id="captchacode" size="25" value="<?php
if(isset($_POST['captchacode'])){
    if(sha1($_POST['captchacode']) == $_SESSION['captcha']){
         //add the comment to db or whatever
    } else{
        echo "The code u provided is invalid. Try again.";
    }
}
?>"/><br />

<p><input type="submit" name="submit_comment" id="submit_comment" value="Add Comment" /></p>
</form>

Link to comment
Share on other sites

Ive tried adding the below code to the process.php but its not working:

<?php
if(isset($_POST['captchacode'])){
    if(sha1($_POST['captchacode']) == $_SESSION['captcha']){
         //add the comment to db or whatever
    } else{
        echo "The code u provided is invalid. Try again.";
    }
}
?>

 

This is how my process.php looks:

<?php
if (isset($_POST['submit_comment'])) {

    if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['comment'])) {
        die("You have forgotten to fill in one of the required fields! Please make sure you submit a name, e-mail address and comment.");
    }

    if(sha1($_POST['captchacode']) == $_SESSION['captcha']){
         //add the comment to db or whatever
    } else{
        echo "The code u provided is invalid. Try again.";
    }
}

    $entry = htmlspecialchars(strip_tags($_POST['entry']));
    $timestamp = htmlspecialchars(strip_tags($_POST['timestamp']));
    $name = htmlspecialchars(strip_tags($_POST['name']));
    $email = htmlspecialchars(strip_tags($_POST['email']));
    $url = htmlspecialchars(strip_tags($_POST['url']));
    $comment = htmlspecialchars(strip_tags($_POST['comment']));
    $comment = nl2br($comment);

    if (!get_magic_quotes_gpc()) {
        $name = addslashes($name);
        $url = addslashes($url);
        $comment = addslashes($comment);
    }

    if (!eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
         die("The e-mail address you submitted does not appear to be valid. Please go back and correct it.");
    }

include "connect.php";

@ mysql_connect($server, $connect, $pass) or die(__LINE__. mysql_error());
@ mysql_select_db($database) or die(__LINE__. mysql_error());


    $result = mysql_query("INSERT INTO php_blog_comments (entry, timestamp, name, email, url, comment) VALUES ('$entry','$timestamp','$name','$email','$url','$comment')");

    header("Location: entry/journal.php?id=" . $entry);
}
else {
    die("Error: you cannot access this page directly.");
}
?>

 

 

Link to comment
Share on other sites

Here is the simple method I use to prevent spam on my guestbook:

 

function nospam() {
  document.book.NOSPAM.value = "NOSPAM";
  return true;
}

 

document.book is the form, which has a hidden variable called "NOSPAM.  The submit button looks something like this:

 

input type="submit" name="gb_action" value="Post" class="input" onclick="nospam();">

 

Then the code to test for spammage is:

 

if ($_REQUEST['NOSPAM'] !== 'NOSPAM') {
  # Whoops, someone didn't click the button.
  print "This site requires javascript, blah blah blah";
}

 

Like tibberous' method, this only works against automated spammers, not real people.

 

Forms can be named like this:

 

<form method="post" action="addentry.php" name="book" enctype="multipart/form-data" onsubmit="return checkForm()">

 

Note the name="book".  The form can then be referred to in javascript as document.book

Link to comment
Share on other sites

dont think i applied it right coz i am still getting spam adverts!

 

i put this in the javascript:

function nospam() {
  document.book.NOSPAM.value = "NOSPAM";
  return true;
}

 

and i added this to my form:

<form method="post" action="../process.php" name="book" enctype="multipart/form-data" onsubmit="return checkForm()">

<input type="submit" name="submit_comment" id="submit_comment" value="Add Comment" class="input" onclick="nospam();"/>

 

i wasnt sure where to put this so i didnt add it:

if ($_REQUEST['NOSPAM'] !== 'NOSPAM') {
  # Whoops, someone didn't click the button.
  print "This site requires javascript, blah blah blah";
}

Link to comment
Share on other sites

Hmm, you will need to alter your existing form, rather than adding new lines.

 

You should alter your existing form tag and add name="book"

 

Then you should alter your existing submit input, and add the "onclick" attribute.

 

The last thing you need is this:

 

<input type=hidden name=NOSPAM value=SPAM>

 

That's a hidden variable in your form, defaulting to "SPAM".  If a user runs the javascript when they submit the form, then it'll be changed to NOSPAM.  That's how you can detect usage of the form by a bot that does not interpret javascript.

Link to comment
Share on other sites

Also if it was a human or a realy clever bot that did interpret javascript you could make some kind of validation to check for certain keywords.

For example

$posttext = "how ever you retrieve your text posted from the submit form";
if (eregi("advertisment", $posttext)) {
    echo "Your post matches words that are related to advertisments, please refrain from using these words."
}

This is one way of going about it but it can annoy your users depending on what words you choose to ban.

Link to comment
Share on other sites

k i think i applied this JS technique correctly but someone/something is still leaving irrelevant comments! They always say "thank you good site" with a stupid url linking to rubbish!

 

This is a comments page on my site:

http://www.newmedia.lincoln.ac.uk/jecgardner/entry/journal.php?id=4

There supposed to be 2 comments one from Igor and the other from webnoob but there is a stranger that keeps coming back and i have to delete there comments!!!

 


This is my form now which looks right to me!
<form method="post" action="../process.php" name="book" enctype="multipart/form-data" onsubmit="return checkForm()">

<p><input type="hidden" name="entry" id="entry" value="<?php echo $id; ?>" />
<input type="hidden" name="timestamp" id="timestamp" value="<?php echo $commenttimestamp; ?>">

<strong><label for="name">Name:</label></strong> <input type="text" name="name" id="name" size="25" /><br />
<strong><label for="email">E-mail:</label></strong> <input type="text" name="email" id="email" size="25" /><br />
<strong><label for="url">URL:</label></strong> <input type="text" name="url" id="url" size="25" value="http://" /><br />
<strong><label for="comment">Comment:</label></strong><br />
<textarea cols="25" rows="5" name="comment" id="comment"></textarea></p>
<img src="captcha.php" />

<input type="text" name="captchacode" id="captchacode" size="15" />
<input type="hidden" name="NOSPAM" value="SPAM" />
<p><input type="submit" name="submit_comment" id="submit_comment" value="Add Comment" class="input" onclick="nospam();"/>
</p>
</form>

 

I would like to get the captcha to work maybe this can stop them?

 

 

Where would i apply this?

$posttext = "how ever you retrieve your text posted from the submit form";
if (eregi("advertisment", $posttext)) {
    echo "Your post matches words that are related to advertisments, please refrain from using these words."
}

Link to comment
Share on other sites

Another good approach is to make all comment require admin approval.

 

You can also use a technique I think I invented but probably didn't. Basically, you make the variable names for the forms random, with the one for message always derived from the one for the name. Don't write these files to the html, write these files as javascript that rewrites itself.

 

So, instead of being able to spam the form with the same values, he has to convert some form-creating javascript to the correct input names, then use those to spam. This only protects against scripted-bots, doesn't protect against macro's or a live person.

This blocks people from using your comment system unless they want to run javascript.

Anyways, if a browser can automatically understand it and parse it, so can a spam bot, so they should be able to get around it.

 

That's why all the big-names use either complicated captchas, or manuel comment approval by admins.

Link to comment
Share on other sites

I dont know how to install an approval system. I dont know if i have installed this JS right?

 

I know for a fact i havent installed this captcha correctly because when i submit a page with incorrect digits it still posts the comment :( I would like to get this working. I dont know what i am doing wrong

Link to comment
Share on other sites

OH misunderstood what you were saying sorry.. ^^

 

Basically just make it so comments have a tinyint column that defaults to 0, and don't show up unless it's set to one.

 

Then in your admin panel or whatever have something that lists comments that have it set to 0, and an option to delete it or set it to 1 (approve).

Link to comment
Share on other sites

I am trying to get mathguard to work to stop bots from using my form. This is what my form looks like: http://www.newmedia.lincoln.ac.uk/jecgardner/entry/journal.php?id=5

 

If i fill in all the options except the maths question the comment still submits. The point of having this maths question is so if the user/bot cant figure out the answer then the comment wont submit. Please can someone tell me why the comment still submits?

 

This form works with 3 pages 1. comments page (journal.php) 2. process.php 3. ClassMathGuard.php - i am trying to link the three... If the user doesnt enter an email with the @ sign then the comment won't submit so this validation works. I just cant get the mathguard to work!?!?!? Please help!

 

Comment form:

<form method="post" action="../process.php" name="book" >
<p><input type="hidden" name="entry" id="entry" value="<?php echo $id; ?>" />
<input type="hidden" name="timestamp" id="timestamp" value="<?php echo $commenttimestamp; ?>">
<strong><label for="name">Name:</label></strong> <input type="text" name="name" id="name" size="25" /><br />
<strong><label for="email">E-mail:</label></strong> <input type="text" name="email" id="email" size="25" /><br />
<strong><label for="url">URL:</label></strong> <input type="text" name="url" id="url" size="25" value="http://" /><br />
<strong><label for="comment">Comment:</label></strong><br />
<textarea cols="25" rows="5" name="comment" id="comment"></textarea></p>
<? require("ClassMathGuard.php"); MathGuard::insertQuestion(); ?>
<input type='hidden' name='action' value='submit'/>
<p><input type="submit" name="submit_comment" id="submit_comment" value="Add Comment" class="input" onclick="nospam();"/>
</p>
</form>

 

process.php:

<?
/* first we need to require our MathGuard class */
require ("ClassMathGuard.php");
/* this condition checks the user input. Don't change the condition, just the body within the curly braces */
if (MathGuard :: checkResult($_REQUEST['mathguard_answer'], $_REQUEST['mathguard_code'])) {
echo ("Great !"); //insert your code that will be executed when user enters the correct answer
} else {
echo ("Bad answer, go back to school !"); //insert your code which tells the user he is spamming your website
die();
}
?>
<?php
if (isset($_POST['submit_comment'])) {

    if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['comment'])) {
        die("You have forgotten to fill in one of the required fields! Please make sure you submit a name, e-mail address and comment.");
    }

    $entry = htmlspecialchars(strip_tags($_POST['entry']));
    $timestamp = htmlspecialchars(strip_tags($_POST['timestamp']));
    $name = htmlspecialchars(strip_tags($_POST['name']));
    $email = htmlspecialchars(strip_tags($_POST['email']));
    $url = htmlspecialchars(strip_tags($_POST['url']));
    $comment = htmlspecialchars(strip_tags($_POST['comment']));
    $comment = nl2br($comment);

    if (!get_magic_quotes_gpc()) {
        $name = addslashes($name);
        $url = addslashes($url);
        $comment = addslashes($comment);
    }

    if (!eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
         die("The e-mail address you submitted does not appear to be valid. Please go back and correct it.");
    }

include "connect.php";

@ mysql_connect($server, $connect, $pass) or die(__LINE__. mysql_error());
@ mysql_select_db($database) or die(__LINE__. mysql_error());

    $result = mysql_query("INSERT INTO php_blog_comments (entry, timestamp, name, email, url, comment) VALUES ('$entry','$timestamp','$name','$email','$url','$comment')");

    header("Location: entry/journal.php?id=" . $entry);
}
else {
    die("Error: you cannot access this page directly.");
}
?>

 

ClassMathGuard.php:

<?
class MathGuard {

/** A main hashing function: concat of user's answer, hour and the additional prime number (default 37) */
function encode($input, $prime) {
	return md5($input.date("H").$prime);
}

/** This function generates the hash code from the two numbers 
 * @param $a 	first number
 * @param $b	second sumber
 * @param $prime	additional number to encode with
 * */
function generateCode($a, $b, $prime) {
	$code = MathGuard::encode($a + $b, $prime);
	return $code;
}

/** This function checks whether the answer and generated security code match 
 * @param $mathguard_answer		answer the user has entered
 * @param $mathguard_code		hashcode the mathguard has generated
 */
function checkResult($mathguard_answer, $mathguard_code, $prime = 37) {

//		echo("prime; $prime, $mathguard_answer");
	$result_encoded = MathGuard::encode($mathguard_answer, $prime);

	if ($result_encoded == $mathguard_code)
		return true;
	else
		return false;

}

/** this function inserts the two math term into your form, the parameter is optional */
function insertQuestion($prime = 37) { //default prime is 37, you can change it when specifying the different parameter
	$a = rand() % 10; // generates the random number
	$b = rand() % 10; // generates the random number
	$code = MathGuard :: generateCode($a, $b, $prime);
	echo ("<a href='http://www.codegravity.com/projects/mathguard'>MathGuard</a> security question: $a + $b =
			<input type='input' name='mathguard_answer' size='2'/><input type='hidden' name='mathguard_code' value='$code' />");

}

/** this function returns math expression into your form, the parameter is optional 
 * quite simmilar to insertQuestion, but returns the output as a text instead of echoing
 */
function returnQuestion($prime = 37) { //default prime is 37, you can change it when specifying the different parameter
	$a = rand() % 10; // generates the random number
	$b = rand() % 10; // generates the random number
	$code = MathGuard :: generateCode($a, $b, $prime);
	return ("<a href='http://www.codegravity.com/projects/mathguard'>MathGuard</a> security question: $a + $b =
			<input type='input' name='mathguard_answer' size='2'/><input type='hidden' name='mathguard_code' value='$code' />");

}

}
?>

Link to comment
Share on other sites

this is the same problem i am experiencing with GuiltyGear's captcha....

 

@ Azu - I can probably add another column to my comments table with tinyint default 0.

 

This is how my blog comments table currently looks like without adding a new column:

php_blog_comments_ss.gif

 

I have a page called editcomments.php which lets me see all the comment entries and I can then click on each comment entry and edit or delete each one seperately.

 

How would I go about determining if an entry is 0 or 1? This method comes across complicated

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.