Stop SPAM in your site being invisible. A honeytrap for Drupal comments form

Share |

If you can see me, you're not human

The concept is quite simple. SPAMbots browse the Internet like mad searching for forms to fill with their crap about enlarging things and meds for your little soldier friend not getting hard enough and all that. OK, this is the game, they want forms to fill, we'll give them some.

I'm a geek, so I have a plan:

Step 1: We modify the comments form and add a new field, but we hide it to the user, so only a machine can see it.

Step 2: If our secret form field is not empty, we got the SPAMbot.

First steps

We're gonna put some code here in our site, so you'll need a place for it. I always create an empty module named 'hacks' for every project where I add all my custom stuff, so I have everything in a single place. If you don't know how to create a module, just spend 5 minutes here:

http://drupal.org/node/416986

You can skip all things theme related from this tutorial. We don't need a theme file nor theme functions for this task.

Remember that after creating and uploading your own empty module, you have to go to the admin panel and enable it!

The code

Step 1: Modifying the comments form.

This is the code that makes the magic:

function [--foo--]_form_comment_form_alter(&$form, $form_state) {
	$form['#validate'][] = 'honeytrap_check';
	
	$form['honeytrap'] = array(
		'#type' => 'textfield',
		'#title' => 'Leave this field blank',
		'#weight' => 0,
		'#required' => false,
		'#default_value' => ''
	);
}

This code makes two things. One, it tells the comments form that besides normal validation process, it must also validate against a function called honeytrap. Second, it adds our honeytrap text field to the comments form.

Just remember to replace [--foo--] by your module's name and that's it.

Step 2: Check if our honeytrap field is empty. If it's not, reject the comment.

function honeytrap_check($form, $form_state) {
  if (!empty($form_state['values']['honeytrap'] ) ) {
    watchdog('notice', 'SPAM attempt at '
.$form['form_id']['#value'].' form', NULL, WATCHDOG_NOTICE);
    form_set_error('honeytrap', 'We told you to leave this field blank');
  }
}

As an extra nice detail, besides rejecting the comment, the function stores a message in Drupal's registry about the (failed) SPAM attempt.

Hiding the form to the humans

Oh, that's an easy shot. Just open your theme's CSS file and add this line wherever you want:

#edit-honeytrap-wrapper {display: none;}

And that's it. The SPAM in our comments are now under control. Enjoy a more simple life now.

Comments
nachenko on Fri, 02/12/2010 - 11:34

Ladies and gentlemen, our first (failed) SPAM attempt comes from Moscow!

IP: 195.42.xx.xx

Marc-André Lanciault (not verified) on Fri, 02/12/2010 - 13:31

Dude, this is very nice ! So easy, but genious! How did you came up with that stuff ?

Great work!

nachenko on Fri, 02/12/2010 - 14:09

In the end, it's just analytic thinking. We know Spambots don't bother with images, CSS and Javascript. Anything based on this can do the trick. I chose using CSS to keep the accesibility of the method as high as possible.

My method does not ban the SPAMer, as it could be a disabled user using Lynx or some screen reader. The user is returned to the same screen and he's given instructions on how to proceed to properly submit a comment. The instructions are very simple: leave blank the field entitled "leave blank".

Anyway, if eventually SPAMers find the way to my site, I have other tricks in mind...

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <pre> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <img> <h2> <h3>
  • Lines and paragraphs break automatically.