Using JavaScript to Prevent Comment Spam

A method that I use on my personal site to prevent blog spammers from posting to my comments.

The Problem

Comment spam (also known as ‘link spam’, ‘blog spam’, and ‘wikispam’) occurs when people or spam bots post comments on someones blog, guestbook, or wiki for the sole purpose of boosting traffic and promoting better search engine rankings for their site. Like email spam, it can be particularly annoying and troublesome to deal with.

Common Solutions

Many companies and organizations have put forth efforts to prevent comment spam. The well-known search engine Google, who owns the popular blog site Blogger, announced back in 2005 that it would no longer index anchor tags with the rel="nofollow" attribute in them. Web developers were encouraged to make their software automatically add this attribute to all user-contributed hyperlinks. Although this method will discourage a lot of spammers from wasting their time, it doesn’t actually prevent them from posting spam comments.

Other efforts to combat comment spam focus on the fact that most spammers use automated scripts to submit their messages. These scripts work very much like traditional spam bots but, rather than harvesting email addresses, they target comment forms. Once spammers have a list of comment forms and know the fields that each one asks for, they can use programs like cURL to forge comment submissions. This is an effective way to spam many blogs in a short period of time, so it’s used quite commonly.

A reasonably good method of preventing this type of spam is called CAPTCHA. CAPTCHA typically displays an image of a word or phrase with obscured lettering that OCR scanners can’t read. This means that, to successfully submit a comment, the user has to provide the correct response to the CAPTCHA test. Since a human is typically required to pass the test, spam bots can’t post bogus comments to sites that use this technology. Unfortunately, this method requires users to take additional steps in order to post comments.

Of course, you could require that all comments be approved before they are posted, but that requires a lot of extra time and effort, especially for busy sites.

A Better Method?

I’ve decided to share a method that I’ve been using on my personal site for a few years now. I used to get lots of guestbook and comment spam on a daily basis when my forms were left wide open. Since I’ve applied this technique, I haven’t recieved any comment spam at all. That’s right, not one. Of course, once I post this there will be nothing stopping spammers from tweaking their bots to work around this solution. At least, for now, it works extremely well.

How it works

It’s really quite simple. You start with a basic comment form:

<form id="comment-form" action="add-comment.php" method="post">
    [other input fields here]
    <input type="submit" value="Post Comment" />
</form>

Now, to prevent comment spammers, we make a few basic adjustments:

<form id="comment-form" action="NO-BLOG-SPAM.PHP" method="post">
    [other input fields here]
    <input type="button" value="Post Comment" onclick="submitCommentForm();" />
</form>

Notice I changed the form action to NO-BLOG-SPAM.PHP. This could be anything, really, as long as it’s not a valid page. Next, I changed the submit button to a regular button and added a JavaScript onclick event. I’ll show you the submitCommentForm() function in a minute. First, I want to explain my reasoning for doing all this.

It makes sense to me to have a bogus action so that, when a spam bot indexes the form information, it is indexing a submission page that doesn’t exist. If the spammer was trying to use cURL to submit the comment, they would receive a ‘Page Does Not Exist’ error.

It also makes sense to me to change the submit button to a regular button. If the spam bot is trying to submit the form from the within the page, it won’t know which field triggers the submission. In fact, it would have to be smart enough to follow the JavaScript events for every form element that has one (which, in our case, is only one).

Now, here’s the submitCommentForm() function. Note that I am including this function from a separate file, which means the spam bot would not only have to be able to follow the JavaScript, but also support including scripts from other parts of the page.

function submitCommentForm() {
    // Change the form action to the real submission page
    document.getElementById('comment-form').action = "add-comment.php";
    // Submit the form
    document.getElementById('comment-form').submit();
}

As you can see, the when the user clicks on the button labeled ‘Post Comment’, the submitCommentForm() function is triggered. This changes the form action to the real submission page, allowing the user’s submission to post. Of course, this still won’t prevent a real human from submitting comment spam, but humans aren’t usually into wasting countless hours of their time typing in comment spam. As I stated before, this method has prevented automated comment spam on my personal site for well over two years.

Pros

Cons

Comments

Nice. Take it a bit further and remove the button entirely.

<form action='nospam' method='post' id='comment-form'>
... [Fields] ...
</form>

<span id='comment-post' onclick='submitCommentForm()'> Post Comment </span>

<style type='text/css'>

#comment-post{
display:block;
height:1.5em;
width:10em;
background-color:#CCC;
border:2px solid #333;
cursor:pointer;
}
</style>

... something like that. You could also create the whole form (or at least it's elements if you want to go the easier route) using javascript and DOM.

Also, why not use mod_rewrite to restrict any requests to the javascript file that don't come from your domain. Easy to spoof, but redundancy is great.

Why not hash the form and input field names on the server using md5 then hash to check for the input. On the server side it would look something like this (in php):

$comment=$_POST[md5('comment-field')];

Where the comment field name was:
44ded89abcb17fcc9f3374a7ccf41afe

You could do this with the form id too. All this and you never had to bother your users for anything but enabling javascript. Nice. Now we just need a good solution for human spammers. Enter rel="nofollow".

#1 Dustin on May 11th, 2007

Very good suggestions to take this process a step further, Dustin. I especially like the MD5 encryption of the field names, since JavaScript doesn't have a built in function to handle that.

Coincidentally, A Beautiful Site just got it's first comment spam today (which is my fault for leaving the form wide open), so I'll be implementing this method this weekend.

#2 Cory S.N. LaViska on May 12th, 2007

I'm sorry to hear about your comment spam. Definitely let me know how the tweaks you make to your algorithm work out. Creating the form with javascript and DOM would probably be the most effective approach for two reasons: 1) any scanners wouldn't find a form on the page (unless they were parsing javascript) and 2) users without javascript enabled wouldn't see the form at all (no headaches).

When I mentioned mod_rewrite above I meant checking the referrer. Which I still think is a good idea.

I personally think your technique is one of the better ones out there.

Thanks for the great post!

#3 Dustin on May 12th, 2007

Thank you. Very cool! kokoben19, mucha gracias!

#4 noabat17 on Jul 17th, 2007

nice site

#5 paul on Jul 23rd, 2007

I am about to implement your idea. Thanks!

There is only one thing you are missing and that is a method of not only preventing the spam bots so that it delays them for as long as possible before they know if the post went through.

#6 omegaman66 on Aug 16th, 2007

1. Bots found my guestbook.
2. Post many many times in short periods of time (to fast to be human)
3. Turned the link to the form page into a javascript link so new bots will not find it.
4. No follow etc already implemented.
5. Added your script. Bots still add just as many comments.
6. Figure they aren't sending the info from the actual form but instead already know what the form should look like and send the link request straight from their own computer.
7. Pull out hair! Scream. haha
8. Renamed the file the form points and corrected my referrences to it but still the bots post.
9. I am going to put a javascript that checks the referrer and redirects them if it is from a different url than mine.

Your scipt should help with NEW bots but at least one kind of bot is giving me fits still.

#7 omegaman66 on Aug 17th, 2007

My mistake. I had forgotten to move the url off of the add comment page and onto its own page called by javascript. Once I did that no more spam!!!

Awesome job!

#8 omegaman66 on Aug 17th, 2007

Thank you! Was looking for some way to implement an antispam form submission solution and did this in 5 minutes. Spamming stopped. I like this better than CAPTCHA which annoys the water out of me and my customers more. Extremely simple and inventive!

#9 Rusty on Oct 12th, 2007

Looks beautiful, but one more question:
In order to make a stick form a do a php 'self' command in the action. Which now I transfer to the little bit of Javascript. And does not work anymore. So: any suggestions about how to make a sticky form this way?Thanx erwin

#10 Erwin Engelsma on Nov 19th, 2007

Interesting, I never thought about that before. But is it working on Firefox or another browser ?

#11 Ash Knight on Feb 27th, 2008

Captcha is good when you can read it, but sometimes the whole process seems to try hard to drive away useful comments. I like the system where you enter a required word that requires thought. Like, type in the colour of a lemon. Only humans know that.

#12 Malliobiana on Jun 5th, 2008

Great tip. I had to clean my comment page everyday of tens, even hundreds of spam comments. I implemented your tip in a few seconds and everything is working great with no spam. Thank you.

#13 Dan on Jul 17th, 2008

hrhrhr

#14 atul on Jul 18th, 2008

Great tip. I had to clean my comment page everyday of tens, even hundreds of spam comments. I implemented your tip in a few seconds and everything is working great with no spam. Thank you.

#15 anand on Jul 18th, 2008

I do a similar technique on my website. However, I have the script's default action point to a PHP script that store's their IP address in an sql database. Then, I have a cron job that runs every minute and adds those ip addresses to my Apache's .htaccess file in order to ban them. After 24 hours or more, the IP is removed. This stopped TONS of bot comments and alos prevents the bots from further harassing / scanning / probing my site. It has done wonders.

#16 Matt on Jul 25th, 2008

sss

#17 ss on Jul 31st, 2008

Add a comment

Name*

Email*

Never, ever sold or spammed :)

Homepage

Comment*

Sorry, plain text only :(