Best unobtrusive anti-spam technique (Not CAPTCHA)

I know you are probably thinking that this will be some silly thing, but this idea that Thomas Landauer came up with is by far the best I've seen in a long time.

How does it work?

Well the idea is relatively simple: Add CSS-hidden fields that a user won't see, but a spam-bot will fill. Then using php check if they were filled, and if they were: block the spammer!

The CSS would be something as simple as:

  1.  
  2. .noshow { display:none; }
  3.  

The HTML form should include something like this:

  1.  
  2. <label for="leaveblank">Leave this blank</label>
  3. <input type="text" class="noshow" id="leaveblank" name="leaveblank" /><br />
  4. <label for="dontchange">Do not change this</label>
  5. <input type="text" value="http://" class="noshow" id="dontchange" name="dontchange" />
  6.  

And finally the php would be simply:

  1.  
  2. if ($_POST['leaveblank'] == '' && $_POST['dontchange'] == 'http://') {
  3. // accept form submission
  4. }
  5.  

The only possible drawback would be that some users with CSS disabled would see the "hidden" form fields, and thus would be quite puzzled.
The good thing is that the percentage of users with CSS disabled is so low that I wouldn't even care about that issue...

I like this idea so much that I'm writing a WP plugin to do this for sure. Just wait for a week or so and I will have version one running :)

Hope to see you when that happens!

PS: If you want me to notify you, comment saying so below, and I'll send you an email when I'm done.

About Alex

Hello! I'm Alejandro U. Alvarez, an engineering student at Universidad de Oviedo (Spain). I started programming during my Freshman year in Brookline High School (Boston, MA), and then got more and more interested in web development. I'm almost in love with JavaScript, although I keep an open mind with other languages

25 thoughts on “Best unobtrusive anti-spam technique (Not CAPTCHA)

  1. Smart move, I was actually thinking about that today.
    I pop online to see how to implement it and stumble on this mere hours from your post.
    I love the internet.

    Please update me when you build it… I will come.

    1. Good idea. I’ve heard it mentioned in a few places and I wonder how successful it is. I’m thinking however that the bot could be able to detect that the field is not visible via CSS. It could inspect the DOM and get past this..

      It would be interesting if you could post your results / measure the amount of spam that you’ve blocked.

      Just a thought :)

      1. So far I have 100% compliance from the spam side of things on one site.
        It usually get 3-4 real requests per day and 30 spam messages.
        Since implementing this change; I get 0 (zero) spam messages (not a typo).

        The alternative from the “noshow” could be to simply blend the text field with the form
        background using css again of course for border, background, and text;
        – this method should allow for 99% compatibility with all browsers.

        When it doesn’t you can use the feature for decoration to display a link or some text.

        I agree with most here however that this feature will get adopted by the masses, then it will definitely need those extra layers of security ( randomness, etc ) that have been proposed.

        Along the lines of the generation of content based on the most simple user interaction which I’ve been considering but aren’t too transparent.
        – you could get the user to type a number between 1 and 26 (provide a chart) based on the first letter of their email; seemed much left cryptic than any captcha I’ve seen.
        – you could also have the user select 2 out of 5 radio buttons. (which 2 could depend on the form content)

        For the purpose of preserving the life of the tool, you definitely need a thank you page so the the operation is transparent to the bot. however that page can inform the real user that they have failed in sending you a message but that they can retry by simply typing the email once more ( that is not too much of a hoop to jump through)

        Enough said for now.

        – od46.com

        1. Your ideas are good, but my goal is to provide a good spam-fighting plugin that will both block all spam comments and allow users comments without requiring anything from the user. Basically I am trying to use the best (unobtrusive) techniques I can find around and put them all together.

          The other main problem is that if this plugin starts to be used a lot, spam bot developers will use its source code to find ways of going around it. Which is why I have to find ways that will make it very hard for them.

          So far this plugin has blocked 23 attempts of spamming in my blog, since I activated it for testing 3 hours ago. Only 2 spam comments actually went past the security walls I had setup. Which means that in this early stage it has a 92% accuracy.

          Thanks a lot for your ideas, I will consider them carefully
          Alex

  2. It’s best to name your hidden fields something along the line of “email”, “url” or “content”. Most bots will use the field-names to filter out which content they need to enter, and this can assure you they will enter something in the hidden field.

    Though it’s not a guarantee this will work for all spam-bots …

    1. Of course I was thinking about something like this. For my first tests I am using names like “personal_email” or “work_email”, as for the plugin itself, I was thinking about developing some sort of “random” name generator, using words like “email, url, website” that bots usually search for. This way bot developers won’t be able to program the bots to detect this plugin and go around it.

      When I have some stats I will publish an article with my research and results, and in a few weeks when the plugin is working and thoroughly tested I will publish it as well.

      Thanks for the ideas.

    2. Of course I was thinking about something like this. For my first tests I am using names like “personal_email” or “work_email”, as for the plugin itself, I was thinking about developing some sort of “random” name generator, using words like “email, url, website” that bots usually search for. This way bot developers won’t be able to program the bots to detect this plugin and go around it.

      When I have some stats I will publish an article with my research and results, and in a few weeks when the plugin is working and thoroughly tested I will publish it as well.

      Thanks for your interest!

  3. I’ve actually been doing something similar for quite awhile now. It is extremely effective. I even had mine setup to add the malicous bot’s IP added to a list in my .htacccess – effectively eliminating them from ever returning to the site. However, I then changed my mind, thinking that, rather than give the bot developer something to challenge them, I’d let them think they sucessfully delivered their spam payload – this way a red flag would not appear to the bot owner and they’d not come to my site personally to investigate.

    Also, this way I can send the bots to a special thank you page (that appears normal to them and keeps them happy) but allows me to easily remove them from my stats – and of course I don’t get any email notices or anything when they do get to this page since the script does nothing but load the bot-thankyou page.

    It’s been working great for a couple of years now on both my site and several of my clients. I’ve thought about writing about the method, but I’ve been kind of selfish, not wanting this technique to get figured out by the spammers so I’ve just quitely kept it to myself. heh heh

    But, since you’re posting it, I guess I’ll contribute something:
    Hiding your form field with display:none; may not be ideal, lots of bots will not fill anything with display:none; since they figure if you don’t want visitors to see it, then they don’t need to either… Kinda the way input type=hidden works.

    Maybe use a negative margin on the input you want to hide instead?

    1. Your ideas seem really good, and I will follow all the recommendations you’ve said. I’m also concerned by the issue you’ve mentioned, bot developers programming their bots to go around this security measure, which I’m sure they’ll try if this plugin becomes popular…
      Because of that I am trying to develop all sort of “random” name generators for the field names, which will create names always containing email, url, website and other important keywords.

      About the CSS issue, I’ll try to find a good way of hiding the fields without the bot being able to notice it… Either with the margin or with the size I still don’t know how.

      First I’ll get everything else to work, like the processing, and the implementation of the extra fields, and then I’ll start working on the details like improving the CSS, and the overall security.

      Thanks a lot for the ideas!

  4. This sounds like a neat trick. I am sure making a bot to go around css display none or negative margins wont be tough, but none the less, it is definitely an easy way to at least add an extra layer of security.

    Maybe an even better way to counter this would be to actually show the field and ask the user not to enter anything here!!! This way, the “human” genuine user does not enter anything in that field while the bot does!

    1. That would actually be a great idea, but it would contradict the goal of this technique: Fight spam without the user noticing anything…

      I am sure that bot developers will eventually find a way around this, or will teach the bots how to read CSS, but we can always make it so hard to figure out that no one will ever understand it.

      Another way I was thinking about was to position it under the real form elements using negative top margin. For example under the field Name, we could place another field that shouldn’t be filled…

      But anyway, this requires a lot of thinking, and first I need to get the plugin to work ;)

  5. Sounds like it might work. Depends on how complicated the site is as far as hiding the CSS.

    I found that most bot developers actually look at the code thoroughly. I added a hidden timestamp field on one of the sites I developed. The bot coders actually scripted the timestamp into their submission engine to make it seem like it took 2-3 minutes for submission.

    There is a drawback to giving a legitimate person a thank you page, when you’re flushing their email because they matched a bot pattern because they assume their message to you has come through. That’s fine for a personal website, but in corporate situations, you have to make sure you’re not discarding valid emails.

    What I noticed is if I can hash something that’s unique to that user’s session(not necessarily a session var), without causing a real end user grief when they forget something like their email address, then I have something for comparison to make sure they’re at least using my form and not simply posting to my form handler. Nothing says they’re even using your form at all.

    My latest approach takes a couple of hashes and a random number. I hash their IP and the random number together, then i hash their user agent. Since most bots don’t actually have to use your form for submission, it’s a good idea to try and make your handler force submission through your form. I hash their user agent because that changes when they start implementing the bots too. It has to be exactly the same for it to match for a hash. I also flush the email if I get an empty user agent. In addition I pass the hashes via GET and the random number via POST.

    Surprisingly, some of the spam I get via forms is a real person pasting links and so forth. I’ve got keyword blockers on some of my forms that look for flag words and look for words without vowels. Don’t get too many of those in everyday speaking. I also bounce emails that have BBcode in them. In short, it will cut down on headaches, but there will always be someone who takes the time to fill out the form just so they can let you know they have beaten you.

    Another approach I’ve used in the past is a reverse dictionary attack. I used bayesian logic to develop a pattern for good submissions via the form. Depending on the form, it could be people sending their contact info, maybe even requesting information. Since most spam doesn’t sound like real content this can work in a variety of situations.

    If something flushes it’s a good idea to write it to a log, that way you can check for false positives as well and fix the code if trouble arises. Also remember to use Regular Expressions.

    1. I have to say that it is good to have someone with so much experience on the subject helping here.
      My aim is to develop a plugin that will represent a decrease in spam of at least 80% for every user, with absolutely no interaction from readers.
      My ideas right now are the hidden fields technique, and I will probably give a try to some of your techniques.

      This plugin is turning way more complex than it seemed when I started its development!

  6. Another security measure would be when PHP initially loads the page start a timer and measure the time until a form or comment gets posted. Bots are very fast, humans logically not so fast filling the form.

    Combine this with your strategy and maybe it will be the next best anti spam method. Even Microsoft is tackling this strategy.

    1. This would also work for some bots, and I will implement it for sure, although not all bots will fall for this… There are many who are starting to include scripted timers to slow down the post time, to seem more human.

      If everything goes as planned, the plugin will use several “invisible” techniques that the reader won’t even notice to stop spam, and become this way the most silent option when fighting spam.

      Thanks for the idea ;)

  7. Nospam testing has now started. It is installed and running in my computer, and by now, instead of deleting comments it is sending them to Akismet… I think it is safer, since it allows the comments to be recovered.

    It is giving me some interesting results, although I still need to work on it :)

    Thanks for everyone’s support

  8. I use a similar technique, but with less things around (no css)

    document.getElementById(‘aRandomName’).value=’something’;

    I suggest to use aRandomName just to avoid specific patches from the spammer.
    You will check that aRandomName is equal to “something”, in this example.

    Note that spam bots usually doen’t change hidden values,

    1. Not to the WordPress plugin repository. I tested it on this blog for almost a year, improving most of it.

      I’m actually using this system on all the contact forms I ever use, it works amazingly. But I’m not sure if this is necessary for blogs, where Akismet is already doing a great job.
      Another reason is that this works as long as bot devs are not aware of it. If many people start using it, workarounds will appear and it will stop being as effective.
      If you like the idea implement it, but don’t tell too many people!

Leave a Reply