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:
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!
Cool! That's a module I'd be happy to test and use.
The
db_query()function to update the 'access' table is found inuser_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-...
Post new comment