HTML & CSS - - By Martin Psinas

Easy Spam Prevention Using Hidden Form Fields

Maybe I’m old-fashioned or a purist, but there’s one aspect of usability that’s severely lacking on many websites. I’m referring to the insanity surrounding spam prevention.

As noted in a personal blog entry back in November 2011, I was having some issues with spam and came up with a solution that I’ve come to learn isn’t really new, but that few people seem to use or know about. It’s an extremely simple yet effective method of preventing spam on your website forms that I’d like to share with you here.

The Problem

Obviously as your website grows in popularity, the spam invariably increases. There are several well-known methods of spam prevention including:

  • Banning IP addresses
  • Forcing users to register and verify their email before posting
  • CAPTCHA images or similar Turing tests
  • Third-party solutions which use ever-growing databases of known spammers to compare against
  • Manually moderating or approving posts

The problem with the majority of these methods is that the users suffer. Banning IP addresses rarely works because those can be spoofed or reassigned and you might actually end up blocking a legitimate user; spammers tend to use dynamic IPs anyway.

Forcing users to register or read a difficult CAPTCHA image shifts the burden from the website owner onto the user, causing them to have to jump through more hoops to contribute. CAPTCHA images are a horrible solution anyway in that they don’t cater well to those with disabilities and they’re also increasingly vulnerable to OCR (Optical Character Recognition) programs.

I don’t want to rely on some third-party solution because the fewer dependencies I have in my project the better I’m going to feel about it. If that leaves me manually sorting through spam for hours on end then so be it, so long as the burden is mine. Some people will argue that the added complexity is a necessary evil, but I just can’t seem to bring myself to agree.

The Solution

So there I was deleting spam after spam trying to think of a non-intrusive solution when I started noticing a pattern … a spambot cannot distinguish the difference between whether or not fields are optional or required, so it just fills them all out. If you think about it, every website is different when it comes to marking required fields; some do it with asterisks, some with red text, some with the still poorly supported HTML5 attribute “required”, and others don’t bother to mark them at all, but rather redirect you back if you happen to miss one. It only makes sense that a bot would get tripped up on such a thing and simply not even try.

Eureka! There it was, a Turing test that was built in to my application all along! Now how to make the most of it.

Not only do spambots struggle with recognizing required fields, but they also struggle with reading CSS or JavaScript, at least for now. The simplest solution, then, is to add a completely arbitrary field to each form and then to hide it using any number of such methods, for example:

<input type="text" name="foo" style="display: none;">

Alternatively, you could opt for something a little more complex like giving the field an ID or a class which would then force the bot to scan through your CSS files to determine the element’s visibility.

You could also use Javascript to remove the arbitrary field from display as the page loads, for example:

<div id="fooDiv">
<label for="foo">Leave this field blank</label>
<input type="text" name="foo" id="foo">
</div>
<script>
(function () {
    var e = document.getElementById("fooDiv");
    e.parentNode.removeChild(e);
})();
</script>

Notice how the field in the example has been given a label instructing the user to leave the field blank on the off chance they have JavaScript disabled.

Now you can rest assured that if the field ever has a value when the form submission reaches your server then the transaction can be discarded as junk. No matter which method you use the bot now has the added task of figuring out whether or not a given field is visible and/or required, which you could argue would take some pretty advanced AI or a more targeted approach on behalf of the spammer.

It might also help to randomize where the arbitrary field is displayed and how it is named so that it is even less predictable.

Of course, no solution is completely foolproof, as spam is sometimes still manually submitted by humans, so it never hurts to have more than one prevention procedure in place. To add another layer of protection, when spam is detected you should still go ahead and redirect the bot as though it were a successful form submission; I don’t like to give them any reason to probe.

I love good, old-fashioned, out of the box solutions, especially when they are elegant and work. I hope you find this trick as equally useful as I have, and I hope you’re willing to share any improvements or some other solutions you might happen to come up with.

Comments on this article are closed. Have a question about HTML? Why not ask it on our forums?

Sponsors