I call this the “Three Strikes” Spam Prevention Plugin.
This plugin is designed to prevent comment spam from even hitting your system and leaving you with a flood of approval requests and a bunch of comments to be deleted. While dealing with some moderated comments on my system, I started to realize that most of the REAL Spam could easily be categorized as delete fodder by a “fuzzy” points system. In toying with the idea and testing the various scenarios, I have put together a plugin that keeps tracks of the “strikes” of a comment and then prevents the comment from ever getting into your database and making more work for you.
Here are the possible strikes (so far in the beta):
- Every SpamWord (default WordPress) match within the comment is a single strike
- A greater than allowed number of links inside a comment is a strike
- A match between the commenters’ IP and a SpamWord IP is a heavily weighted strike
- An empty referer field for the posted comment request is a strike
The strike system can be configured to be aggressive or moderate by a simple value change. I have it set at 3 and it seems to work well at that level. Higher numbers = more moderate spam checking (less spam gets deleted). Various users might have to play with that value to see what works for them.
Once a commenter/comment is determined to be “Struck Out”, they are redirected to (by default) the FBI site. This redirect site can be configured in the plugin as well.
The plugin can be downloaded here. Please post suggestions and bugs.
Installation is very simple. Just copy the plugin to your wp-content/plugins directory and activate through your admin interface. I suggest the use of a more moderate spam checking (SpamThreshold greater than 3) and the use of Kitten’s Spam Words for the first few days/weeks till you have some spam words filled up. The more robust your Spam words, the more effective this plugin.
[EDIT] For a method to get notified of Spam when it gets bounced, check out this comment.
[EDIT] 10/3/04 – There is a small bug in this plugin where the WordPress comment approval/delete was borked because of this plugin. To fix the problem, just download the plugin again and copy it to your plugins folder. In other words, the problem has been fixed in the download.
[EDIT] Now with Trackback checking built in.
You may also wish to have it do a “demo” spam check.
For instance, have it process all (or a large sample) of previous comments so that users can see what kind of comments will be accepted, moderated, or just bounced.
That is a great idea! I will have to think about how to implement that though.
Works like a charm (tested on my local machine) – though I guess one thing that would be nice would be to have it email you (as comments get emailed, when you have that option enabled) when it has diverted someone away. Couldn’t see how to do that. Or would it happen anyway?
Actually, I monitor strikes as well as keeping track of who got diverted. Look at the source of this page to see the strikes for each comment. I also have the script send me an email when it gets triggered. I will post that part of the script here in a few.
Look towards the bottom of the plugin and find
//This is where the strikes are processed.
if ($strike >= $SpamThreshold) {
header("Location: $RedirectSite");
die('Too Bad Spammer');
}
Replace that with:
$_POST['comment'] .= "<!-- strikes = ".$strike." -->";
//This is where the strikes are processed.
if ($strike >= $SpamThreshold) {
// Your email address
$email = "your@email.com";
// The subject
$subject = "Mail from blocked comments";
// The message
$message = $comment."<br />".$author."<br />".$email."<br />".$url."<br />".$userip."<br />"."<!-- strikes = ".$strike." -->";
mail($email, $subject, $message, "From: $email");
header("Location: $RedirectSite");
die('Too Bad Spammer');
}
Now, replace your@email.com with your real email address.
Very nice. I had previously tinkered with setting blacklist to auto-block. This might be a better approach.
FYI, one thing I did slightly differently. I worried about false positives, which are a real possibility with any filtering. And I didn’t want someone to type up a great comment, inadvertently trip a filter, and lose their comment. So my die looks like this:
{
echo (‘Your Comment: ‘);
echo ($comment);
echo (‘
‘);
die( __(‘Sorry, but some of the content of this comment appears to violate our comment policies. This determination has been made using filtering software. If you believe you have received this message in error, please contact us by e-mail as soon as possible. In addition, please note that this comment will not be saved on our server. Therefore, if you wish to preserve any of the content of this comment, you should copy it from this screen right now. Thank you.’) );
}
I like Kaimi’s suggestion, though what’s frustrating is that what we *want* to do is slow the spammers down. But I don’t think they wait for the site to respond. I expect they have systems that spew out these spams by connecting to the site and pressing the buttons and ignore any response *at all* from the systems they’re targeting.
How then do we get the server to hold them up? And do they ever, ever look to see if their stuff appears? Only IP banning would work, I suspect, but that’s not going to work because they use networks of Trojanned machines.
This feels like trying to eradicate malaria. Some damn fool keeps leaving empty tyres out in the rain.
I don’t currently have a blacklist and yet any comment anyone tries to post gives 5 strikes right away – why is this?
Try adding one word to your blacklist, not sure what else you have installed.
I’ve dropped this in along with my other WP plugins, but it never appears in the Plugins admin section. Anyone else had this problem?
What version of WordPress are you using?
I’m in the process of converting an MT blog to WP. I have about half my old posts uploaded. I have the WP blacklist, Kitten’s Spam Words, and Three Strikes plugins. The first test comment I tried to post, using my own name/email/domain and body consisting of ‘test’ got me redirected to fbi.gov. Deactivating Three Strikes let the comment go through. I haven’t yet messed with the threshold for Three Strikes, so I’m kind of surprised that the default level blocked me.
Make sure that there are no exmpty spaces or line breaks in the common spam words inside your wp-admin. Empty lines would cause problems and I have noticed that Kitten’s spam words sometimes puts in empty spaces.
I’m not getting the IP of blocked comments – which I’d like to see.
My code:
$subject = “Mail from blocked comments”;
// The message
$message = $comment.”
“.$author.”
“.$email.”
“.$url.”
“.$userip.”
“.”“;
mail($email, $subject, $message, “From: $email”);
However the mail I get when a comment is blocked doesn’t have anything in the $userip field. It gets the comment, the author and author email (faked as they are) fine.
Seems like a bug in the code?
Hmmmm….thats weird and not necessarily a bug in the code. Can you do me a favor and look at the comments in your wp-admin and see if there are any IPs recorded there?
Either this is something new that the spammers have started OR your server somehow does not have the $_SERVER superglobal for PHP implemented. The second error can be fixed by making sure that register_globals is turned on for PHP and replacing $_SERVER with $HTTP_SERVER_VARS[‘REMOTE_ADDR’].
For $_SERVER to work, you should be on PHP version 4.1.0 or above.
Sorted it – it was a bug, but in my code. I had put $userip instead of $user_ip in the thing I wanted mailed.
Now have put together a much more comprehensive response, which includes hyperlinks to ARIN and RIPE (as I get Euro-generated comment spam). Here’s the code:
$message = $comment.” allegedly by “.$author.” at “.$email.” Url “.$url.” IP: “.$user_ip.” (RIPE) “.$user_ip.” (ARIN) \n \n “;
Untested so far, but some spammer somewhere has been banging on my server all day, so sure to get tried out in a moment.
agh, my hyperlinks in the code got commented out. If you copy the code above and the text of the link you’ll get close to it. Apologies. I may try to post the code on my site.
OK, and now I’ve worked out what I did wrong. This version now has a lookup so you can do a lookup all round the world for where the IP is coming from. This is if you get an email telling you whether you’ve had blocked comments.
I haven’t put HTML in this because I don’t use an HTML email client. It converts text beginning with http: directly into links. Your mileage, as they say, may vary, in which case you’ll have to write the a href= stuff yourself.
$message = "Comment: "$comment."
allegedly by ".$author." at ".$email." Url ".$url."
RIPE: http://www.ripe.net/whois?form.....earchtext=".$user_ip."
ARIN: http://ws.arin.net/cgi-bin/whois.pl?queryinput=".$user_ip."
LACNIC: http://lacnic.net/cgi-bin/lacn.....N&qr=".$user_ip."
APNIC: http://www.apnic.net/apnic-bin.....earchtext=".$user_ip."
strikes: ".$strike;
mail($email, $subject, $message, "From: $email");
It’s user_ip, that’s why.
…oops, never mind. 😉
BTW, you can use $email = get_settings(“admin_email”); instead of hard-coding $email = “your@email.com”;
Great plugin! It’s just saved me from a positively ridiculous spam run (230 comments in one day. All moderated, but I got all the notices…)
One problem: On my site, the add_magic_quotes lines cause apostrophes to get double-escaped in comments that pass. My guess is that it’s because magic_quotes_gpc is disabled on my server, so both this plugin and the regular WP code run it — and the comments end up with backslashes in front of every apostrophe.
It *looks* like it’s not necessary in the code this plugin runs, so I’ve commented out those lines on mine and things seem to be working OK.
Another suggestion I’d make is having it issue a 403 error instead of redirecting. While I like the idea of sending the spammer to the FBI’s page, chances are it’s a bot doing the posting, and an “Access denied” error is more likely to get noticed in the unlikely event that the bot’s been written well. Simple version:
if ($strike >= $SpamThreshold) {Access Denied, Spammer!
// this next line depends on what version of PHP you have.
// see wp-blog-header for an example
header('Not allowed', TRUE, 403);
print '
Get lost, spammer!
';
die();
}
D’oh! In a comment about problems with escaping, I forgot to escape my HTML sample code! Sorry about that!
print '<html><head><title>Access Denied, Spammer!</title></head><body><h1>Get lost, spammer!</h1></body></html>';
Currently, there aren’t ANY words in my spam words list. I think I’m looking in the right place: Options -> Discussion -> Comment Moderation.
Hi,
thanxs alot for the plugin!
have a question though: when someone leaves the URI blank it automatically gets a strike? if so, is there a way to remove the URI strike, because i would like to make it a non-required field!
That is not true. As long as you allow blank URIs in your blog, comments should still go through. The three strikes plugin does not check it.
1.2.1
Your plugin has saved the day – I was being innundated with spam, and while it all got caught and put into a queue it was still a big nuiscence. Since using your plugin, the numbers have dropped rapidly, and I’m not having to moderate my site comments every day. Cheers 🙂
Hi, I have installed this plugin. But how do I test to see if it is working?
Where are the configuration options? What do we do after activation? How do we set the number (3)?
Hm…. Actually, I use SpamPal (www.spampal.org) – and I haven’t experienced any problems so far… Still I’ll try this plug-in. Thanks!
With warm greetings from Saarbruecken, Germany,
Vitaly Friedman, http://www.alvit.de/vf
All I did was post “test” and I was directed to the FBI page!
Ummm…just FYI for Ella, that plugin is not active on this blog so redirection to the FBI page is impossible.
Nice site!