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

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.

UPDATE: I wrote a new article on this subject to further improve our control over SPAM. You can read it here.

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.

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

IP: 195.42.xx.xx

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

Great work!

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...

Logging to watchdog isn't really that useful. It would be great if this honeytrap module would add access rules based on the spambots' IP addresses.

Great suggestion, Christefano.

I never considered that possibility. Maybe you can already do that by combining some sort of Trigger/Action and core user access rules. If no-one has done something on that, certainly is worth researching.

I have plans to make this a module. Your suggestion surely deserves a place on it.

Thanks!

I have plans to make this a module. Your suggestion surely deserves a place on it.

Cool! That's a module I'd be happy to test and use.

The db_query() function to update the 'access' table is found in user_admin_access_form_submit().

I like this idea! It would make a great module.

Thanks Liz for your comments.

I'll try to make some improvements tomorrow on this subject, and write another blog post explaining them.

We can't win war against drugs, but we can win the war against SPAM. I hope so.

Hey great idea! so simple, I hope it appears as a module soon!

Update! I wrote a new article on this subject to further improving our control over those crappy SPAMmers.

This time we're not being invisible. We're being slow instead.

http://www.isegura.es/blog/stop-spam-your-site-being-slow-flood-control-...

Great idea, and I'd also be willing to test the module when you release it.

One little improvement would be to add a class to the form input and use that to hide it. Multiple inputs will have suffixes tagged onto the ID tag, so on a page with a search and comment form, one of the inputs wouldn't be hidden. So, just add a '#attributes' => array('class' => 'honeypot'), to the form input array.

Cheers!
Chris

I understand quite well why this code is not released as a module. Spam bots might be able to circumvent part of the logic.

Today I finally took the 5 minutes to do exactly what is written in these 2 nice blog posts. I now have one custom module that gives additional protection to comment spam.

Thanks a lot!

Olivier

I'd like to see something similar for registration spam.

Taking inspiration from this (and Chris Shattuck's blog post), I created a small module for the Signup module. Details and .ZIP at http://drupal.org/node/753978#comment-3241086.

Thanks for a simple, elegant solution.

Hi, Rob!

Thanks for sharing your module with the community. I'm very happy you found my blog useful.

Remember, if you need extra protection, you can try this method too:

http://www.isegura.es/blog/stop-spam-your-site-being-slow-flood-control-...

I have plans to make this a module. Your suggestion surely deserves a place on it.

thanks

Thanks, Sohbet. If you write this module, please let me know!

I like this idea! It would make a great module.

As I am a beginner, I would like to know how to test this module.
I created the three files, fill them according to your article and to the drupal documentation, I modified the css file.
But now ???

А! merci amigo! grand poteau!

Thank you for another informative blog. Where else could I get this kind of info written in such an incite full way.

I would like to know how to test this module.
I created the three files, fill them according to your article and to the drupal documentation, I modified the css file.

HOw to test it? Easy one.

Use Firefox. Install Web developer toolbar for Firefox if you don't have it. In the developer toolbar, select "CSS -> Disable styles -> all styles". You'll see your page without CSS, and your form too. Just fill the form, including the trap field, see what happens.

That’s a really good tip. I never thought of searching comments before. Those darn spammers are getting better at making it less obvious. Fortunately I have multiple sites, so its easy for me to see if someone’s left a duplicate comment. I also delete anybody with keywords as a name pretty much immediately. It makes you want to not be a do-follow blog sometimes.

Wow such a simple idea... but so easily overlooked - You are a genius. I am using captcha for my registration page, but I am thinking I will impliment your idea for my forum area - just to play it safe.

Next all I need is an automated way to stop humans that spam.

Thank you veyr much for this great idea =D

Thanks for reading, Dain. Hope this helps you.

I'd like to see something similar for registration spam.

Registration is just another form, you can apply this method too. Look for tutorials on "how to modify a form in Drupal", the first time requires some time, but it's not difficult.

In one of my wordpress site, I get many spam comments and I trash those comments because they are no relevant to my website though i already use Captcha to stop.

if comments relevant to my site then I always approve but is there any module or plugin to stop these spam comments?

Help me

Thanks in advance

Wordpress? Did you try Akismet?

http://wordpress.org/extend/plugins/akismet/

ah great code i like the way you described it step by step this is why i like CMS they are just epic.
css menu

You are a genius. I am using captcha for my registration page, but I am thinking I will impliment your idea for my forum area - just to play it safe.

Next all I need is an automated way to stop humans that spam.

Thank you so much for this post.

My site http://www.PaperDemon.com has been slammed with bot after bot of spam in the forums and on blog comments. I've tried both math and image captchas but they haven't stopped the bots.

My site isn't a drupal site so i couldn't use the code verbatim, but the concept was clear enough that I was able to write my own implementation.

I've implemented both the timestamp and the honeytrap ideas on my site. Let's see how it goes. I hope this stops those awful spammers. If you have any other ideas for how to stop this type of spam, please email me (or post another comment. I'm subscribed to new comments!).

Thank you again!

HI, BogusRed. I'm glad you found my post useful.

I'm not sure about this, but if you're using Wordpress, I've been contacted by some people interested in writing a Wordpress Plugin based on these ideas. Maybe the plugin is writen and released.

BTW, my own site enjoys a detection rate over 99% using just the methods you read here. Ain't it cool?

Other methods you should research are Javascript based. I'd try to know how many of your users have Javascript enabled. If the rate is close to 100% you have really interesting alternatives.

Oh, and your site is pretty cool. I think I'll follow your site on Facebook!

I'd like to understand how to test this particular module.
We created the actual three documents, fill them based on your article and also to the drupal paperwork, I altered the css document.

Im having trouble getting this to work. The honeytrap field shows up in the comments form, but the css to hide it isnt working.

Also, I added a function to put it in the user registration form (used hack_form_user_register_form_alter). Not sure I did this right, I made a duplicate the first function directly under it and changed the hook. Didnt work.

I tried using Rob's module for the Signup module, and had to make some changes (made it drupal 7 compatible, and changed "signup" to "user" in .info because Im using the User module). But his isnt putting a field into the user reg form either.

I am really lost here and am thinking its a simple fix. Any help would be appreciated.

Thanks!

The first question is: OK, the field is not hidden, but does it work? If you write something on it, the comment should be REJECTED. This is what should happen.

Yes, it does work. The one for the comments section works great.

Man, if it works you did the hard part.

On the CSS part, if you don't know why isn't it applying, you don't know how to diagnose a CSS problem, and if you don't know how to diagnose a CSS problem, it's quite probable you are not using Firebug for Firefox. It's the FINAL solution for CSS problem diagnosis. So you should begin by installing Firebug for Firefox and learning how to use it. Every minute you invest on learning Firebug is an hour saved in the future. Trust me on this one.

I just downloaded firefox this morning. I'll have get the firebug deal too. So that will help me troubleshoot the css.

Can you help me out on the user reg problem too? I cant get that one to show the field. Does it need a separate module? Or should I be able to just add a function to the hacks module?

You just add a function to the module you already have.

By using Firebug, you'll also be able to know what's the name/id of every form that Drupal puts into screen. When you understand Firebug, you'll wonder how could you live without it.