posted on:February 18, 2008

Fighting Form Spam With Css


Fighting form spam is something almost every website owner has to face. If you allow comments on your site you will most likely be a subject of form spam attacks. The most effective and most popular way of fighting form spam is using generated images (captchas) that contain text that user should then retype into an input field. Since there are OCR algorithms that can read images, most of the time captchas contain messy and distorted text.

Fresh Solution

Messy and distorted text can be annoying to users, that it can prevent them from posting a comment. One more thing that can make to think twice when it comes to using some of the existing captcha solutions, is the fact that you can’t control their appearance. Generated images can be, well – ugly! To a delicate designer soul that can be even greater issue than spending time every day moderating comments.

So how about we call CSS to the rescue.

The trick I am using on my comment forms doesn’t appear to be that much different from regular captchas. But there is a great difference.
As we said there are some OCR technologies that can recognize symbols on the image. But in order for that to work you must have an image to start with.
Well, I don’t use <img> tag so OCR doesn’t apply to this trick. Instead, I use background image displayed with css. You’ll agree when I say that there’s absolutely no way that a robot can scan your html, locate your css file, compare css selectors, find a css definition, locate the image and read the image using OCR algorithm.

Here’s a sample code from my form. You can of course use the same principle on your own form’s markup.

The html code

<p>
	<label class="captcha" for="captcha">Answer?</label>
	<input type="text" name="captcha" id="captcha" />
</p>

The css code

label.captcha{
	display:block;	
	background:url(/images/captcha.gif) no-repeat 0 0;		
	height:28px;
	line-height:28px;
	padding-left:90px;
	margin-bottom:.5em;
}

Good sides

Good sides would be having easiest possible captcha and ability to design it anyway you like. You can put your own text, simple mathematical function, whatever…

Downsides

Downside to this trick is that people browsing your site with css disabled readers can’t tell what you’re asking them to do. Unfortunately, using this trick you prevent a part of your audience from commenting.

Enjoyed the article?

Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.

DeliciousStumbleUpon RedditSubscribe

Comments (39 Comments)

  1. Catar4x
    February 18, 2008

    Great idea with css ! Cssglobe forever :p
  2. Brian Rock
    February 18, 2008

    Nifty solution, although I suppose it would be possible to improve the auto-spam-bot to search for background-images if no captcha image is found. Wouldn't be easy, but spammers will go to great lengths... Another CSS tactic I read about was creating an extra field that didn't hold any meaningful data. Alter the CSS so a human won't see it. Then if a value is filled in, you know it was an auto-bot doing the spamming.
  3. warnis
    February 19, 2008

    I think this solution is quite poor. Some form of captcha, like recaptcha seem like a much more accessible approach than this is. If you somehow could give users and alternative way of getting the data that would still bypass the spam bots as well then everything would be fine (I was thinking of the title="" attribute but I don't think that will cut it). One way that I have thought of would be using the noscript-tags to wrap an input element and then hide the input via CSS. Very few UAs would render that input (javascript and CSS disabled) and you could always give it a meaningful label (please dont fill this in or something). I don't know whether spam bots read content inside of noscript-tags or not so I guess it needs to be tested.
  4. James
    February 19, 2008

    Never say never!
  5. Felipe
    February 19, 2008

    What Firebug can find easily can be learned to a bot in a matter of minutes. IHow long does it takes to a spammer to learn to its bot that CSS rule learn.captcha in default.css has a link to an image? Wait, it isn't even an external CSS so the link won't change (or cache browsers would prevent regular users to see the recent image they should have seen and answered) So you just have to read http://cssglobe.com/v3.0/images/human_check.gif and I wonder if the image is changed session-based, daily (I can spam for a few hours now, great) or never (ouch, just have to learn a bot to enter "4" in the 3rd text input) ?
  6. Jermayn
    February 19, 2008

    Ok a question! How do you get the captcha image to display different math questions? Would you have to use some more script?
  7. cssglobe
    February 19, 2008

    I maybe went too far saying that image can't be located. You can use different css selectors or even apply class with JavaScript. Can bots read JavaScript? You can also make it really complicated to bots once they find your image. i.e. your image could say "Enter third letter from the word IGNORANT". Adding some more script you can make it as dynamic as you want, you can have several images appearing randomly. Actually, the idea behind this was more of aesthetic nature. I wanted to avoid ugly captcha images and have something that blends more into my design. Not to mention that I hate retyping barely recognizable letters.
  8. Barney
    February 19, 2008

    The problem with all captcha is that they require hassle on the user's part. What I find infuriating with standardistas is that they'll say, "Hey, downside to this is a certain section of users - those using Lynx source code carved into a stone tablet - won't be able to use universal generic web tech from 1992"... When in fact realistic concerns would be "My users don't have time for this comment-customs crap", "My users don't necessarily have 20/20 vision", "My users might not be good at maths". So: # Create an additional field at the front of your form. # Label it " First name** ". # Style it to display:none. # Write an explanation for those CSS-disabled users (we should really start a charity for those guys): " ** Leave blank. " # Give that display:none too. # Tell your form not to submit if the form is filled in. Any robot will. The user has nothing extra to do, the code is much simpler, and you can run the same thing, staticly, over and over.
  9. Julien
    February 19, 2008

    What about CSS Sprites? Just a thought: if your captcha image looked like " X Q W O K P M D ", and you just displayed a random portion of the image, via CSS, for the user to copy? (example: " O K ") The OCR would try to copy everything it recognizes in the image, but a human wouldn't. What do you think?
  10. Dennison Uy - Graphic Designer
    February 19, 2008

    Julien that would cause cross-browser compatibility issues in addition to the fact that this will not work on browsers with CSS turned off.
  11. Julien
    February 19, 2008

    you're right.
  12. kik
    February 19, 2008

    Great idea :) regarding the downside - if someone is browsing my website with CSS turned off than go to hell :) I don't want him on my site
  13. Sarah
    February 19, 2008

    Its a great idea! but there are also more ways available to do the same.
  14. Iain Fraser
    February 20, 2008

    Nice idea. As a previous poster mentioned, another trick you can use is create a text area and give it a label of something like "please leave this field blank" and give it a name of "message". Then you use CSS to shift if a few thousand pixels out of the way. The beauty of this method is that it's accessible to screen readers and non-css browsers and you immediately know if you're being spammed. Again though, it's only a matter of time before spammers search for labels that contain the words "blank, empty, don't fill, etc" and marry up to a form field called "message, comments, etc". But hey, it works for now. I like your idea, but I don't like the fact that it's not accessible. Also, you have to realize that if your browser can render it, spammer's software can render it too, it's not that much of a stretch. Nice idea though
  15. Josh A.
    February 20, 2008

    If this technique goes mainstream, bots will learn - at least if you have a class name like captcha. That's not difficult. They can find your CSS file by pulling out the first one with media="screen", and then finding the selector. It won't be easy, but it's not impossible. If you're going to use this technique then give it a class name that's completely irrelevant. That, I would argue, a robot couldn't detect. Personally, I think there are other methods. Check the percentage of links used, or whether real words are used, and make the decision to allow on the server-side. Or use another method.
  16. Fodcj
    February 20, 2008

    An interesiting set of comments and suggestions are coming out of this thread, maybe we will someday be able to beat those g**s
  17. James Coletti
    February 21, 2008

    Remember: CAPTCHA breaking tools aren't always bots, as in autonomous robots scanning for web pages to look for CAPTCHA images they can attempt to defeat. A tool could be developed where the user chooses the image (or DOM element) to be decoded or the image is saved and the process occurs entirely offline!
  18. derek allard
    February 21, 2008

    I'm not a big fan of CAPTCHA - too often the letters are hard for me to read (and my eyes are still good!). The solution I've used with great success eliminates both the form spam and the CAPTCHA. All I do is create an extra form field and set it to display:none. A spam bot always find the hidden entry (which humans would not) and fills it in. Then behind the scenes I have some basic php that states if this hidden field is filled in don't send it to the intended recipient (or enter into the DB, etc.). I realize that if someone turns off CSS the hidden field will display but I'm willing to trade that off for not having a CAPTCHA field to fill in.
  19. Sirius
    February 22, 2008

    How about mixing numbers, text and math, while still keeping it quite simple for a human to solve: Solution one: An image shows three numbers: "34 20 63", and the task is to "Type in the number with the lowest value, multiplied with five:". Solution two: An image shows five numbers: "9 4 6 3 7 2", and the task is to "Type in the sum of the three numbers with the lowest value". There's no symbols (like + - * /) to tell the bot what to do, and the bot doesn't know if it's going to use all of the numbers or only some of them.
  20. John
    February 23, 2008

    Sadly, this doesn't work for spammers that are targeting just one site and develop software specifically for it... which makes the method kinda pointless.
  21. Richard
    March 4, 2008

    Good article
  22. Ralph
    March 7, 2008

    First, thank you for this idea to avoid much more spam every day. Second, we all know, behind the spam are only people the write code for machines. If somebody of spam-code writer will be here they will improve your code to send more spams, it's your job (: Ralph
  23. Test Commenter
    April 7, 2008

    Just trying to see how it works.
  24. Dave
    April 13, 2008

    Thanks so much, this will help tremedously! Dave
  25. Eric
    April 28, 2008

    Thank you for the guide, going to use this in my new website!
  26. Arabia
    June 11, 2008

    very nice method thank you
  27. Nikita Baffix
    June 14, 2008

    Its a great idea! but there are also more ways available to do the same. CAPTCHA breaking tools aren't always bots, as in autonomous robots scanning for web pages to look for CAPTCHA images they can attempt to defeat. Good article.
  28. Miadeo
    June 20, 2008

    Nice trick, I´ll try it. thanks
  29. sander houttekier
    July 23, 2008

    i also use the technique, previously mentioned, i hide a textfield ckecking if the bot has filled it, but even then i think this is not 100% safe enough... if a bot can check for css selectors, and can find a background image, it can also check if a field is hidden or not... (so i believe) thus it might leave fields be when they are hidden.... so my solution, do not hide the field and label but wrap them in a div and hide that one, or if you are using tables (*curse, go to hell, *curse) you can hide your tablerow for example... Sander
  30. smt
    December 1, 2008

    if a bot can OCR your image, how can you be shure it will never learn to understand CSS(when browser libraries already exist for that)?
  31. Busby SEO
    December 2, 2008

    Nice nice nice....it was not in my mind. Before i just add it in HTML. Little bit clear now. Thanks
  32. Busby SEO Test
    January 7, 2009

    Thanks a lot for the code... now i get more idea for getting unspamm friendly form :) Regards.
  33. busby seo test info
    January 13, 2009

    Nice tips. I'll use it :)
  34. Inventory Management Software
    January 21, 2009

    this is new to me, i will learn and try it myself.. thanks for the tips dude.. :)
  35. Barbara
    January 30, 2009

    just testing
  36. craig
    February 7, 2009

    you will need to change you captcha image constantly do you ?
  37. gosip artis
    April 11, 2009

    Cool idea on using css for fighting spam. Gonna try this on my blogs. Thanks for sharing.
  38. redips
    May 1, 2009

    It's worth trying ... thanks!
  39. Kris Utter
    June 16, 2009

    I just implemented this on my site. We'll see how it goes.

Sorry, the comment form is closed at this time.