My Very Own WordPress Anti-SPAM Plugin

, ,

Over the past 3.5 years, my blog has received SPAM Comments Count88,070 SPAM comments. Averaged out, that’s 69 unwanted messages per day. Ouch!

I’ve tried various plugins in an attempt to combat these unsolicited messages but to no avail.

In my quest to fight the pest of SPAM, I stayed away from service-based offerings like reCAPTCHA and Askimet primarily for privacy reasons. Instead, the plugins I tried at different times were all self-contained on my blog. One used client-side scripting to insert a “check to verify you’re not a spammer” checkbox, presuming that spambots can’t run client-side scripts. Another added a couple CSS-hidden form fields, expecting that spambots wouldn’t notice the CSS and instead try to fill in the fields. If I’m remembering correctly, a third asked the commenter to do a simple math problem, like “What is the sum of 2 and 3?,” based on the assumption that a spambot can’t do arithmetic.

Unfortunately, all let way too many junk comments through. I wanted a plugin that would stop the torrent of junk, so yesterday I decided to write my own custom, blog-specific anti-SPAM WordPress plugin.

My Very Own Anti-SPAM Plugin

Why not ask a question that would be easy for an animate site visitor to answer but hard for an automated agent to figure out—like the last name of the person who runs this blog (i.e. my last name)? A human can easily find this answer by scanning over any page on the blog while an automated system will have to be fairly sophisticated to figure out the answer.

Here’s the plugin….

Must Start with the Header

A WordPress plugin always starts with a File Header in a PHP comment block.

/**
 * Plugin Name: Custom Anti-SPAM Plugin
 * Description: A custom-written anti-SPAM plugin just for this blog.
 * Version: 0.1.1 (beta)
 * Author: Ben Gribaudo
 * Author URI: http://www.bengribaudo.com/
 */

Add the Prompt

FieldsTo ask my question, I needed to add HTML to the comment form. I hocked onto the comment_form_after_fields action. This allowed me to insert my HTML after the comment form’s textbox fields and immediately above the comments box.

comment_form_after_fields is only triggered for non-logged in users—perfect in this case because I didn’t want the prompt to appear for logged in users.

add_action('comment_form_after_fields', array($this,'addPrompt'));
function addPrompt() {
	echo "\t" . '<p class="comment-form-caslastname"><label for="caslastname">Last name of the person who runs this blog <span class="required">*</span></label> <input type="text" name="caslastname" id="caslastname" size="30" aria-required="true" /></p>' . "\n";
}

Check the Response

I wanted to reject SPAM outright (vs. saving it as a SPAM-tagged comment), so I attached my response-verifying code to preprocess_comment. Listeners to this action are called at the beginning of the comment processing pipeline and are passed an associative array containing data about the comment.

add_filter('preprocess_comment', array($this, 'verifyPrompt'));

The method verifyPrompt first checks if filtering should be run on the comment at hand. Only regular comments should be filtered and the filter should only be run if the visitor is not logged in. If the comment is a pingback or trackback (signified by a non-empty comment_type) or if the user is logged in (signified by a non-empty user_ID), verifyPrompt exits without filtering.

The filter’s logic is simple: compare the user’s response, ignoring case and any leading or trailing white space, to the correct answer. If the user gave an incorrect answer, stop processing and display an error message.

function verifyPrompt($data) {
	if ($data['comment_type'] != '' || $data['user_ID'] != '') {
		return $data;
	}

	if (trim(strtolower($_POST['caslastname'])) != 'gribaudo') {
		wp_die('<strong>ERROR</strong>: Please enter the last name of the person who runs this blog.');
	}

	return $data;
}

All Together

The complete plugin, wrapped in a class:

<?php
/**
 * Plugin Name: Custom Anti-SPAM Plugin
 * Description: A custom-written anti-SPAM plugin just for this blog.
 * Version: 0.1.1 (beta)
 * Author: Ben Gribaudo
 * Author URI: http://www.bengribaudo.com/
 */

 class CustomAntiSpam {
	function CustomAntiSpam() {
		add_action('comment_form_after_fields', array($this,'addPrompt'));
		add_filter('preprocess_comment', array($this, 'verifyPrompt'));
	}

	function addPrompt() {
		echo "\t" . '<p class="comment-form-caslastname"><label for="caslastname">Last name of the person who runs this blog <span class="required">*</span></label> <input type="text" name="caslastname" id="caslastname" size="30" aria-required="true" /></p>' . "\n";
	}

	function verifyPrompt($data) {
		if ($data['comment_type'] != '' || $data['user_ID'] != '') {
			return $data;
		}

		if (trim(strtolower($_POST['caslastname'])) != 'gribaudo') {
			wp_die('<strong>ERROR</strong>: Please enter the last name of the person who runs this blog.');
		}

		return $data;
	}
}

new CustomAntiSpam();

So far, it’s worked wonderfully! No more automated SPAM! Yay!

1 thought on “My Very Own WordPress Anti-SPAM Plugin

  1. Jeffrey

    I like your solution. Although I’m not a programmer, I’ve found that the spam on my Blogger blog has greatly increased greatly in recent months. I think Google automatically blocks most of the spam comments, but I still get email notifications about them.

    Reply

Leave a Reply to Jeffrey Cancel reply

Your email address will not be published. Required fields are marked *