06/07/2006

WordPress Spam Blocker

I've been promising for some time to post my WordPress spam blocker — essentially a bit of code that blocks comment spam from being posted in WordPress — so here it is.

Now, I've blocked IP addresses either at the server level (in httpd.conf) or via .htaccess, but blogspammers tend to hit a page half a dozen times at one go from different IP addresses. So you end up with a long list of blocked IPs which may not have belonged to the spammer in the first place. Of course, comment moderation works; while I moderate comments because I am forced to do so, there's something intensely offensive about finding blogspam in your Comments Moderation list. The problem is that the spammers were able to post even though their posts weren't published due to the comment moderation being on. What I wanted was a way to block spammers from posting in the first place without blocking endless numbers of possibly bogus IP addresses.

I found the genesis of my code in a post at the WordPress forums which suggested adding this code to wp-comments-post.php:

$url = trim(strip_tags($_POST['url']));
if (strpos($url,"poker") !== false) { die("Denied");}
if (strpos($url,"anotherspamword") !== false) { die("Denied");}

This works fine but, because it's case-sensitive, requires at least three entries for each spamword. So I ran it by my friend/programmer extraordinaire, Darin, who changed the base code so that case-sensitivity is no longer an issue.

Full WordPress spam blocker code

Note: this has been tested in WordPress 1.2.2 and 1.5; I haven't tested in WP2.0 because I haven't dealt with 2.0.

In wp-comments-post.php (of which you've made a copy, right?), after the code addressing author, email, URL and comments (around line 33):

$comment = trim($_POST['comment']);
if (eregi("spamword",$comment) !== false) { die("Denied");}

This causes submission of a comment containing the spamword to go to a page that says "Denied" and blocks the comment from being posted. Well, good enough. But there are more fields in the comment form, and we find spammers getting plowing individual keywords and URLs into the other fields, too:

  • name
  • email address
  • URL
  • comment

So here's the code for the full set of WordPress fields; just substitute your word(s) [including dashes, where needed] for "word1", "word2", etc.:

$author = trim($_POST['author']);
if (eregi("word1",$author) !== false) { die("Denied");}
if (eregi("word2",$author) !== false) { die("Denied");}

$email = trim($_POST['email']);
if (eregi("word1",$email) !== false) { die("Denied");}
if (eregi("word2",$email) !== false) { die("Denied");}

$url = trim(strip_tags($_POST['url']));
if (eregi("word1",$url) !== false) { die("Denied");}
if (eregi("word2",$url) !== false) { die("Denied");}

$comment = trim($_POST['comment']);
if (eregi("word1",$comment) !== false) { die("Denied");}
if (eregi("word2",$comment) !== false) { die("Denied");}

Yes, you end up with a rather lengthy list, but it's effective, and your Comment Moderation queue is no longer defaced with those types of comments. It does require a little care in selection of spamwords — if you run, for instance, a real estate site, you wouldn't want to block real estate-related keywords.

Otherwise, it's terrific. I get about eight spam comments a week. Little do those latecomers know that they're just adding to my list of spamwords — including domain names. <grin> Since comments go into the moderation queue, I just save the spam comments until I see a pattern, then add them to the above list.

Now, I also have another wish: since I have a few WordPress blogs, and a few clients with WordPress blogs, I mentioned to Darin that it would be great to separate the spamword list from the WordPress files so that, instead of editing and uploading each WP file, I could just FTP the spamword text file to each web hosting account. He's working on it, though neither of us has tested it much so far.

ADDED: I've used the above method for years. However, when we moved (yes, we're now a Reno / Sparks web design company), I found Conditional Captcha … which is about as pretty a thing as I've seen in a long time. Do give it a spin, as it only presents the captcha to commenters who are already in the Akismet database. Nifty.

7 Comments to "WordPress Spam Blocker"

  1. Harry Maugans says:

    Ah, very nice. About a month ago I got tired of cleaning up the comments on my own blog, so I went out looking for an anti-spam script. I ended up deciding on "dr Dave's Spam Karma 2", which has worked out great. It has thresholds and uses a semi-intelligent algorithm in deciding if it's spam or not. For example, if someone clicks on a post of mine, and a few seconds later posts a comment (ie, no time to read it), it flags as spam. :)

  2. DianeV says:

    Excellent — that's another way to go.

    Although, now that I think of it, I believe normal spam blockers flag spam, but it still lands in the WordPress moderation queue. The above script doesn't do that — it blocks spam comments from being posted at all. Pure bliss. :)

  3. Goodwin says:

    Nice idea!
    I think the code could be optimized a little:

    $spamwords = array('word1','word2','word3'); // spam words to search for
    $postfields = array('author', 'email', 'url', 'comment'); // $_POST fields to check
    foreach($postfields as $postfield)
    foreach($spamwords as $spamword)
    if(eregi($spamword, $_POST[$postfield]) !== false)
    die("Denied");

  4. Diane Vigil says:

    Interesting. If the first line could be one per line, that would make a much tidier file.

  5. Goodwin says:

    You cat rewrite it to look like this:

    $spamwords = array(
    	'word1',
    	'word2',
    	'word3',
    );
    
  6. Diane Vigil says:

    Thanks!

  7. DianeV says:

    Having thought about it, the only problem I see with combining the spamwords for all the fields is that it *could* make posting certain things difficult.

    I've had a bit of trouble with that, where I couldn't use a non-spam word that I would normally use. Had to edit the thing. <grin>

    And so, I look forward to (whenever we finish) the coding for the external files for the spamblocker.

Have your say ...

First-time comments will be held for moderation (but comments are appreciated). Otherwise, just be courteous. If your name is a bunch of keywords, your comment will be deleted. Don't post links unless highly pertinent. Posters must be 16 or older.

Manage your subscriptions

Archives
© 2004-2017 DianeV Web Design Studio. All Rights Reserved.
34 queries. 0.248 seconds.