
Spam is a nuisance, and you know it. Happilly, WordPress users have Akismet, which help a lot to fight spam. But what about protecting your blog even more? This recipe might help.

Spam is a nuisance, and you know it. Happilly, WordPress users have Akismet, which help a lot to fight spam. But what about protecting your blog even more? This recipe might help.
Paste the following code in your functions.php. Comment that contain any of the words contained within the $bad_comment_content array will be automatically rejected.
function in_comment_post_like($string, $array) {
foreach($array as $ref) { if(strstr($string, $ref)) { return true; } }
return false;
}
function drop_bad_comments() {
if (!empty($_POST['comment'])) {
$post_comment_content = $_POST['comment'];
$lower_case_comment = strtolower($_POST['comment']);
$bad_comment_content = array(
'viagra',
'hydrocodone',
'hair loss',
'[url=http',
'[link=http',
'xanax',
'tramadol',
'russian girls',
'russian brides',
'lorazepam',
'adderall',
'dexadrine',
'no prescription',
'oxycontin',
'without a prescription',
'sex pics',
'family incest',
'online casinos',
'online dating',
'cialis',
'best forex',
'amoxicillin'
);
if (in_comment_post_like($lower_case_comment, $bad_comment_content)) {
$comment_box_text = wordwrap(trim($post_comment_content), 80, "\n ", true);
$txtdrop = fopen('/var/log/httpd/wp_post-logger/nullamatix.com-text-area_dropped.txt', 'a');
fwrite($txtdrop, " --------------\n [COMMENT] = " . $post_comment_content . "\n --------------\n");
fwrite($txtdrop, " [SOURCE_IP] = " . $_SERVER['REMOTE_ADDR'] . " @ " . date("F j, Y, g:i a") . "\n");
fwrite($txtdrop, " [USERAGENT] = " . $_SERVER['HTTP_USER_AGENT'] . "\n");
fwrite($txtdrop, " [REFERER ] = " . $_SERVER['HTTP_REFERER'] . "\n");
fwrite($txtdrop, " [FILE_NAME] = " . $_SERVER['SCRIPT_NAME'] . " - [REQ_URI] = " . $_SERVER['REQUEST_URI'] . "\n");
fwrite($txtdrop, '--------------**********------------------'."\n");
header("HTTP/1.1 406 Not Acceptable");
header("Status: 406 Not Acceptable");
header("Connection: Close");
wp_die( __('bang bang.') );
}
}
}
add_action('init', 'drop_bad_comments');
This recipe have been submitted by Guy. Thanks to him for sharing his tip with the community!
22 Responses
or use Akismet (^:
Ouch… Snippet basically prepends sophisticated comment routine (which is multiply functions, hooks, black list, grey list, white list, etc) with single hardcoded blacklist and logs spam to text file instead of spam in WP admin.
Oh and code fires on every single WordPress page, including posts and admin area, most of which have nothing to do with comments.
This is weird on so many levels.
Not really a good option. There are so many better choices than hard coding a spam word list. Bad choice.
Well, works for me. So much for giving back to the community….
@Guy Patterson
No offense.
WordPress has complex and extensive routine to handle comments. Anti-spam plugins count on that to hook their functionality in and count on collected spam to educate and improve quality.
It’s not that your solution doesn’t work – it perfectly does. But it basically works against WordPress code, not together with it.
WordPress has native blacklist – you use your own.
WordPress white lists comments from moderators – you might kill their comments before it gets to that.
WordPress stores spam comments to check for false positives and such – you take them away into unrelated text file.
And so on.
The only trouble with this is that when the core WP code requires an update you have to reapply the hack to the new code.
I used a captcha on one of my blogs and that has pretty much killed the spam comments.
A good second line of defense is something like bad behaviour. Put a trap in your site that only bad bots vist and then block them out via htaccess automatically. This also stops the leeches from sucking up bandwidth.
It’s a nice concept but I think more people would be turned on to this if it were a plugin, Guy. Pasting code into templates scares some people away. The method is a bit primitive but honestly, what other way is there around rejecting it right at the start? Is there one? The alternative is obvious: use Akismet.
You could probably make this into a plugin that pulls terms from an external resource that multiple people contribute to, or allow the user to create their own local terms list. Making this work via AJAX would be handy as well. Although the aforementioned ideas basically loop me back to sticking with Akismet. Most users don’t have a problem with going into their Admin panel and deleting the spam comments in the spam queue manually. All the Akismet dev team would have to do is add an option to automatically delete the comments in the spam queue automatically (on an interval or immediately).
Indeed, duplicates the standard features. Excess hack with dubious opportunities. Yes and spam can be any phrase.
@Andy Holiday
This is snippet for functions.php, it is file in theme and won’t be threatened by core update. Hm, but I think it will be by theme update.
@Daryn St. Pierre
>what other way is there around rejecting it right at the start?
This is hardly at the start. By this time (init hook) WordPress engine, plugins and active theme are already loaded. So there is little to none performance gain, comparing to letting WP handle comment as usual.
@Rarst,
No offense taken, just trying to give a little something back.
I came up with that snippet of code for a number of reasons. Akismet
works great, and I still use it, but when my site was being attacked
by comment spammers (a few hundred comments every couple hour), my
server started crawling. The database had to work extra hard inserting
all that meaningless spam, send the stuff to Akismet, get a response,
etc. And I didn’t like the idea of creating a few dozen IPtable
policies that might block potentially legitimate visitors originating
from the same networks.
The blacklist in the WP admin panel doesn’t blacklist anything, just
flags the comment as spam and inserts the data into the WP database.
To me, a blacklist should prevent any further action in the event of a
positive detection, not continue processing the page/code and
injecting content into the DB. Comparatively, what good is an IPtables
blacklist if the attacker is still able to connect to the
server/service?? Kind of defeats the purpose of a “blacklist” in my
opinion.
I’m not worried about killing a moderator’s comment if their comment
contains one of the words/signatures in the blacklist array. The whole
“check for false positives” thing is nice, but consumes excessive CPU
and bandwidth that’s better spent elsewhere, especially when the
comment form is under a massive attack.
@David
Maybe this isn’t a good option for you, but as I mentioned, works
great for me. What “better” options can you suggest that will prevent
inserting data into the database? Please elaborate as why exactly this
is a “bad choice.”
@art
I do. Akismet doesn’t blacklist the comments as far as I’m concerned.
The comment is still processed, and the attacker receives a 200 OK
status letting them know their comment was accept by the application
and inserted into the database…
@Guy Patterson
Personally I don’t like Akismet and don’t use it at my blog.
My suggestion for your snippet would be to drop hardcoded blacklist and init hook. Instead check approval status in pre_comment_approved filter and wp_die if comment is determined to be spam.
This way you will keep native WP functionality (blacklist, etc) for detecting spam, but will keep it from getting into database.
@Rarst
Ah, ok. Thanks for the suggestion. I’ll work on it and see how it goes.
The code was originally thrown into the wp-comments-post.php, but knowing the majority disapprove of editing the wp-core and the preference for easy implementation, I made the snippet functions.php “friendly” before summiting to wp-recipes.
Anyway, thanks again. I’ll look into the pre_comment_approved filter.
Guy
Just to weigh in on this one – I like to encourage everyone to have a stab at plugin development so I think it’s unfair to shoot somebody down for something they’ve created (I know I’ve created some truly horrendous code when I was learning)
Guy, I think you should investigate Wordpress’ Action Hooks and Filters list (and there are hundreds more in the core files that aren’t on that list, but it’s a great place to start) – then check out how to use them effectively so as not to conflict with Wordpress’ native behaviour and the behaviour of other plugins..
This is definitely a last-ditch, hacky method of stopping spam and not one that I’d suggest if you want to create stunning, future-proof code. Instead of working to find ways around Wordpress’ functionality, try to look for ways to extend it even further.
The WordPress already do this, just go to ‘Settings > Discussion’ and add the rejected words to ‘Comment Blacklist’.
Interesting and useful for general defense purposes, but the built-in WordPress Moderation and Blacklist features provide essentially the same functionality.
I have found that blocking malicious patterns and behavior via htaccess to be quite effective at eliminating a much larger slice of malicious nonsense.
By focusing on broad request patterns and behavior, filtering specific terms via PHP is unnecessary. The scumbags are blocked before they ever see the comment form.
Like someone said, or akismet. I use akismet and i don’t have spam comments.
Only in contact forms, sometimes..
It doesn’t apply when we upgrade the word press version
IMHO akismet does the job very well to protect your blog against spam comments.
isn’t anti spam plugin enough and simpler ?
it’s annoying when we change the themes and change the setting again
Trackbacks: