Alister Cameron // Blogologist

Changing the world. One blog(ger) at a time.

Wordpress comment spam: my simple way to stop (most of) it before it happens

Stop comment spam!I am now averaging over 100 spam emails every day in my Akismet spam trap. So, thank you Akismet.

But being a conscientious kind of guy, I want to make sure a “false positive” hasn’t got quarantined, so I like to go through the spam comments before deleting them, just to be sure.

As your blog grows in popularity, you will probably experience the same problem as I have: that unless you are regimental in checking through the spam comments on a daily basis (and then deleting them), the list gets too large, and it takes too long (and is too painful) to look through them all.

So I needed a better way.

I looked through all the different captcha-style solutions online, but I just didn’t like the idea of adding another plugin to my Wordpress install, let alone a plugin that either a) implemented a rather “heavy” solution to a simple problem or b) relied on javascript to do some sort of funky cookie/hash thing.

In the end all I needed was some way to allow a human to show me they were indeed human… something a machine couldn’t do, thus blocking bots out of my comment form. Well, I came up with something last night and I’m waiting to see how it goes.

A Really Simple Spam Bot Blocker

What I did was add a field to my form (as seen below) where the commenter is asked a question, and needs to give the right answer. You could come up with any question/answer combo you choose, as long as they’re both short and simple. In my case the question asks “Are you human?” and the reply I ask for is my firstname.

The trick with my implementation is that I use a background image in that form field, which explains the answer I’m looking for. That way, anything other than a human being can’t see the answer I’m looking for, and humans actually see the answer right there in front of them.

(What I hate about those maths ones is that they make me think too much. Do you know the difference between a product and a sum? I don’t want to introduce fear and doubt for the commenter about whether they’ve actually entered the right answer. I want to make it really simple.)

As the commenter clicks into that field (if javascript is turned on), the background image disappears, so they can see their typing easily. In case they’re brain-dead and then spell my firstname wrongly, I actually only check on the server side that they’ve started my name with “al”… the rest I ignore. Man, how easy can I make it?! ;)

I use a tiny bit of inline javascript to control the on/off display of the background image of that field, which, if you’re wondering, looks like this:

onfocus="if(this.value=='')
  this.style.backgroundImage='none';"
onblur="if(this.value=='')
  this.style.backgroundImage='url(/images/despam.gif)';"

To create the background image, I typed the text into the field, took a screenshot, then messed around with it in ImageReady, reducing the opacity to 33% so it has the light grey colour. (If that’s too intimidating for you, I found this webpage that creates a GIF image from text you enter, with all the configuration options you need. Way cool!)

The only other thing I had to do was implement the additional check for this new field in the Wordpress file wp-comments-post.php, which is found in the root folder of your Wordpress install.

I found this bit (on line 33 of the WP 2.1.2 version of the file):

if (get_option('comment_registration')
wp_die(__('Sorry, you must be logged in to post a comment.'));

…and added this bit immediately below it:

if ('AL' != strtoupper(substr(trim($_POST['despam']),0,2)))
wp_die(__(’Error: please correctly type my firstname.’));

The PHP code here looks at what was typed into that new field of the comment form, cleans it up, capitalizes it all, pulls out the first two letters only, and compares them to “AL”. If there’s no match, a Wordpress error screen is presented. (That error screen is ugly and would be better inline on the post page, but I don’t care. Real people should never see it.)

My only gripe is that I have introduced a “hack” to my Wordpress installation, meaning that when I upgrade I have to make this edit manually.

(Note: if you copy the above code snippets make sure to check and replace the funny single quotes with “plain” ones or PHP will have a fit. I can’t stop Wordpress using these weird ones, sorry!)

So, what do you think? Is Akismet (or similar) enough for you? What Wordpress plugins do you use to handle spam? Why?

Updates

In the last 24 hours only about 10 spam comments got through to Akismet! How happy am I?! But…

It turns out Safari and some other obscure Linux browsers don’t allow background images in input fields, meaning that my solution doesn’t work for what my stats package tells me is 4% of my readership… and presumably yours as well. Drats and double drats!

(Thank you to very helpful commenter Scott Jangro for pointing this out.)

So I’ve had to implement what turns out to be a simpler solution still, but which relies on javascript being turned on. No background image this time, just a bit of “obfuscated” text that gets injected into the input field onload, saying the same thing as the image did. You’ll be pleased with this solution if you didn’t like the prospect of having to create an image, changing your CSS to suit, etc.

Now the onfocus and onblur event handlers to be added to the input tag look like this:

onfocus="if(this.value==despamVal){ this.style.color='#000';this.value=''}" onblur="if(this.value==''){ this.style.color='#999';this.value=despamVal}"

…and you need to add one line of javascript anywhere below that on the page:

<script type="text/javascript">var despamVal=unescape( "%49%66%20%73%6F%2C%20%74%79%70%65%20%6D%79%20%6E%61%6D%65 %20%27%41%6C%69%73%74%65%72%27%20%68%65%72%65%2E"); document.getElementById('despam').value=despamVal; document.getElementById('despam').style.color='#999'; </script>

Just be aware that all those percent signs and numbers in the javascript above are an “escaped” string of text, to make it that little bit harder to hack/read. I use this page to do the escaping. But this is optional… you don’t have to escape the text if you don’t want to, and I can’t be sure it will positively effect the rate of spam getting past this counter-measure.

I’m sorry for having to update with this change of approach, but I don’t want to alienate/annoy Safari users (it being the preferred browser of most Mac users).

 Add Me
Sphere: Related Content
Internet Marketing Masterminds... success starts here!
  • Look Who's Been Here!

  • My Posts in Your In-box!

    Enter your email address here for instant updates in your inbox, whenever I post something new.
    Your email address is in safe hands. Relax!
© Copyright 2008 Alister Cameron. All Rights Reserved Theme // Sitemap // RSS