Jump to content
Robert Zelník

Comment spam filtering alternatives

Recommended Posts

I would like to have some alternatives to Akismet for comment spam filtering, because Akismet is a bit expensive solution for low traffic small business sites.

Possible solutions:

  • text Captcha (math tasks, simple riddles...)
  • reCaptcha
  • mollom.com integration

Share this post


Link to post
Share on other sites

Good ideas, we'll definitely have to look into these for future updates in the comments module. However, I also want to note that we already do have an alternative built in, that I've found to be just as effective as a captcha (if not more so) on the sites where I use it. Look at the 'requireSecurityField' option in /wire/modules/Fieldtype/FieldtypeComments/CommentForm.php. This option can be enabled in the options to the form:

echo $page->comments->renderForm(array('requireSecurityField' => 'security_field')); 

I typically hide my comment form with CSS to prevent the possibility of false positives:

#CommentForm {
   display: none;
}

Then use JS to show the comment form, and append a security field to it:

$(document).ready(function() {
   var $input = "<input type='hidden' name='security_field' value='1' />";
   $("#CommentForm form").append($input).parent().show(); 
}

No more spam. :) The only downside is that your comment form now requires Javascript to use. But since you are hiding it with CSS and making it visible with JS, at least you won't be disappointing anyone.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks Ryan. It works well, just with two little bugs:

  • the ending bracket in the JS code is missing
  • now it doesn't show the successMessage.

I have changed the code to this:

$(document).ready(function() {
var $input = "<input type='hidden' name='security_field' value='1' />";
$("#CommentForm form").append($input);
$("#CommentForm").show();
});

Share this post


Link to post
Share on other sites

Thanks Ryan. It works well, just with two little bugs:

  • the ending bracket in the JS code is missing
  • now it doesn't show the successMessage.

I have changed the code to this:

$(document).ready(function() {
var $input = "<input type='hidden' name='security_field' value='1' />";
$("#CommentForm form").append($input);
$("#CommentForm").show();
});

Yes, that's right - it does not show the success message anymore then.

If i leave the comment form visible (not hide it with CSS) and use the code as follows it works:

$(document).ready(function() {
var $input = "<input type='hidden' name='security_field' value='1' />";
$("#CommentForm form").append($input);
});

BTW: How does that security field works? I guess it should work as a Honeypot fields, right?

I just wondered because there is a value set for that field - and shouldn't such a honeypot field be a normal text field, just hidden cia CSS?

I tried to find out how it is handled in the Commentform.php and i found this part:

if($key = $this->options['requireSecurityField']) {
if(empty($data[$key])) return false;
}

Now i am much more confused ...

Share this post


Link to post
Share on other sites

It's more of a reverse-honeypot field. Rather than excluding a form based on a populated value, it excludes based on an unpopulated value. This can be even more effective than a regular honeypot, but it does rely on Javascript. In order to eliminate the problem of false positives, you want to hide the CommentForm with CSS and unhide it with Javascript at the same time that you add the security field (as in the examples above).

Share this post


Link to post
Share on other sites

Thanks Ryan. It works well, just with two little bugs:

  • the ending bracket in the JS code is missing
  • now it doesn't show the successMessage.
I have changed the code to this:
$(document).ready(function() {
var $input = "<input type='hidden' name='security_field' value='1' />";
$("#CommentForm form").append($input);
$("#CommentForm").show();
});

I have tried that code now and it works fine - the success message is shown.

@ryan: Does the spam protection work fine using the code above? If i use the code you posted the success message is not shown:

$(document).ready(function() {
    var $input = "<input type='hidden' name='security_field' value='1' />";
    $("#CommentForm form").append($input).parent().show(); 
});

Share this post


Link to post
Share on other sites

Not sure why the follow-up message wouldn't be shown. Was the comment still saved?

Share this post


Link to post
Share on other sites

Yes, the comment is saved - but it does not show the success message when i use this code:

$(document).ready(function() {
    var $input = "<input type='hidden' name='security_field' value='1' />";
    $("#CommentForm form").append($input).parent().show(); 
});

When i use this, it works:

$(document).ready(function() {
var $input = "<input type='hidden' name='security_field' value='1' />";
$("#CommentForm form").append($input);
$("#CommentForm").show();
});

Share this post


Link to post
Share on other sites

Okay, glad that works. There must be a container element between #CommentForm and form, and code in the first example assumes #CommentForm is the parent of form. 

Share this post


Link to post
Share on other sites

Thanks for the reverse honeypot method! I'm now using both a regular honeypot (don't fill the field) and your reverse method in all my input forms.

I can also recommend adding simple logging to see if it works or not. 

if ($honeypot == 1 || $securityfield != 1) {
    	$log = new FileLog($config->paths->logs . 'detectedspam.txt'); 
    	$log->save('Spam catched: '.$sanitizer->textarea($input->post->body));
        $session->redirect($config->urls->root); exit();
    }

30 seconds after I implemented this, I got a spam message logged. urgh.. bitter sweet feeling..

  • Like 4

Share this post


Link to post
Share on other sites

I have a contact form getting heavily spammed. I don't want to pay ransom to Akismet so I found this. I implemented everything here except the dual method listed by woop. However, I am not seeing the Success message. The comment is being added to the db.

This is the JS code I implemented. The form is hidden in CSS then shown with JS.

$(document).ready(function() {
    var $input = "<input type='hidden' name='security_field' value='1' />";
    $("#CommentForm form").append($input);
    $("#CommentForm").show();
});

Thanks for any help.

Anthony

Share this post


Link to post
Share on other sites

Do you see any errors in your JS console?

Are you using any kind of caching (TemplateCache, ProCache, MarkupCache) on the comments or comments page?

Are you using the redirect after post option in your comment settings?

It might also be good for us to get a look at your code that outputs the comment form. 

Share this post


Link to post
Share on other sites

Hi Ryan,

1. No errors in my JS console.

2. No caching on those pages (whatever the PW default is).

3. I am using the Redirect after comment post option.

4. The code that outputs the form (stolen with gratitude from your example):

if ($trailer) {
  $title = $film->title . ' - trailer';
} else {
  $title = $film->title . ' - full film';

  $commentsForm = $page->comments->renderForm(array('requireSecurityField' => 'security_field'));

  $numComments = $page->comments->count();
  if($numComments > 0) $numCommentsStr = sprintf(_n('%d Comment', '%d Comments', $numComments), $numComments);
    else $numCommentsStr = __('No comments yet'); 
}

BTW, at least the bombardment has stopped filling the email notification so that is a start.

Thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...