f w h

Halt Comment Spam in WordPress

The spam comments on this blog got ridiculous. Readers never saw it because I moderated all of them. However, I was receiving 60-80 comments per day, and it took too much to try and sift through for legit comments (I’m sorry if you’ve commented here and it never got posted. I tried).

I was pretty well fed up with it, so I tried plugin after plugin. One made it impossible for anyone without an account to post comments, one didn’t work at all, and I didn’t want to pay for an Akismet key (so I’m cheap, what of it?).

How then, does one take care of this problem? I looked at a number of alternatives. Some possibilities were an “Are you human?” checkbox or Q&A (answer a question like what is 2+4) or traditional image CAPTCHAs. But, I knew I wanted one thing for sure. I didn’t want to put the burden on real people. So, I decided to go with the “honeypot” or invisible CAPTCHAs.

The idea is that because spam bots love to fill in input fields, you can hide one with CSS and halt form submission if the field has a value. Initially, I tried doing this with some fairly simple JavaScript. Intercept the submit button click and return false if the field has a value. Easy, right? Nope. As it turns out, spam bots ignore JavaScript, and there was no change in the amount of spam.

It had to be on the backend. Because I don’t particularly care what a commenter’s website is, I chose that field as my honeypot, and used CSS to hide it from the user’s view. In WordPress, comment submission is handled by wp-comments-post.php in the root. I then added the following to that file at line 82:


if (strlen($comment_author_url) > 0){
	die("Fail sauce");
}

Why line 82? This is after the user information is gathered and stored in variables, but before any actual action is taken. Admittedly, it took a bit find the correct variable I had to use. I certainly could have just used $_POST[‘url’], but I feel like the variable should be used to keep the code consistent. What we’re doing here is taking the number of characters in the website field, and if that number is greater than zero, halting the code from continuing.

Results

The number of spam comments for about the last two years has ranged between 60 and 80 per day. Since implementing this honeypot CAPTCHA 3 weeks ago, I’ve received one spam comment.

One Major Issue

As some might guess, the major issue with this method is that updates to WordPress will very likely undo it. I think that’s a small price to pay for the results.

UPDATE (18 Jan 2014)

As suggested in the comments, I’ve worked out a way to add this CAPTCHA scheme to a theme’s functions.php file. Just add this to the file:


add_filter('pre_comment_approved', 'check_honeypot');
function check_honeypot() {
    if (strlen($comment_author_url) > 0) {
        die("Fail Sauce");
    }
}

This will keep WordPress updates from breaking it.