Inverse Captcha Anti-Comment-Spam Technique: Now A Regular Mephisto Plugin

posted: September 25th, 2007 · by: Sven

in: Programming · tagged as: , , , , , , , ·  36 comments »

After I had revamped my initial experimental approach to the “Inverse Captcha” anti-spam technique as a regular Mephisto Plugin lately I have promised to explain how you can use it to get rid of your blog comment spam.

This plugin is getting a bunch of additional attention these days, especially after it was linked to in Quarks’ Ruby on Rails Security Guide. So, some additional information is past due. There you go.

The inital experiment

When I first came across Damien’s description of the “Negative Captcha” technique I wanted to give it a test-drive. I decided to do the ”simplest thing that could possibly work” and happened to implement a fully-functional, highly efficient anti-spam outer floodgate mechanism in two super-simple steps:

  1. I hid the email form input element through CSS from the real users eyes. (Additional I added a warning message in case a user would have disabled CSS that would instruct him to not enter an email address.)
  2. In MephistoController#dispatch_comments I checked whether a stupid bot had filled in an email address and if so, kicked him.

That worked surprisingly well.

I had expected that there would have been at least some Watir- or whatever-kind-of-cool-engine driven bots that would correctly interpret the CSS directive and thus not post back any email addresses. (I’m pretty confident that these bots would be picked up by Mephistos build-in Akismet support, so that’s what I mean by the “outer” and “inner floodgate” metaphor.) Not at all. Nothing. Nada. This super-simple technique actually blocked all of the comment-spam from my blog!

Obviously a major drawback of my implementation was that I discarded the opportunity to enter an email address. But knowing your users email addess sometimes turns out to be a pretty useful thing when you want to directly get in contact with a user. I clearly wanted to re-allow users to leave me their email address.

Also, after I had tested the technique for a couple of months I decided to revamp this stuff as a plugin so that I wouldn’t necessarily need to patch Mephistos codebase in order to get this in.

Make it a regular Mephisto plugin

When you think about extracting things into a plugin you think about how things can be abstracted away from the special case at hand to fit a more general purpose. Also, you naturally try to find some more descriptive or declarative way to illustrate things.

So I sort of invented the concept of undercover-agent-like “sneaky” HTTP parameter that behaves like follows:

  1. It hides its real purpose from bots by obfuscating its original name (of course real users will know its purpose because they don’t look at the input field’s names but at the HTML labels or descriptions)
  2. It allows for a strawman stand-in fake parameter which bears the parameter’s original name, so that bots are lured into filling out this fake parameter (which real users won’t see at all because we’re hiding it through CSS, just like in the original, simple approach)
  3. It un-hides itself when the HTML form is posted back to the application. It does this in the :before_filter stage, so that the Controller does not need to know anything about what’s going on here at all.
  4. It notices when the strawman parameter has been filled in so that it safely can be assumed that a super-stupid-bot™ is trying to drop some garbage - so we’re able to kick him.

Well … I don’t know about you but I am probably lacking some creativity to think of an different usecase where this concept of “sneaky parameters” could probably applied. Can you? Tell me :-)

How to use this?

Basically, to use this, you’ll have to:

Check out the plugin:

script/plugin install

… will work fine.

Tweek your comment form template:

We don’t have access to your templates from a Mephisto plugin. So you have to do this yourself.

Somewhere in themes/[site]/[theme]/templates/_comment.liquid make sure that you have a field like this:

<label for="{{form.sneaky_email_codename}}">E-Mail</label>
{{ form.sneaky_email }}
<p id="comment-email">
    If you can read this, you don't use a typical webbrowser that plays nice with CSS. <br />
    <strong>Please do not fill in anything here!</strong><br />
    {{ }}

And somewhere in your CSS files add a rule to hide the #comment-email part from the user:

#comment-email {
    display: none;

This will output HTML form elements like these:

<label for="comment_soyjjncmhaju">E-Mail</label>
<input type="text" id="comment_soyjjncmhaju" name="comment[soyjjncmhaju]" value="" /> 
<p id="comment-email">
    If you can read this, you don't use a typical webbrowser that plays nice with CSS. <br />
    <strong>Please do not fill in anything here!</strong><br />
    <input type="text" id="comment_author_email" name="comment[author_email]" value="" /> 

Obviously, to real users the form will look just like about any other blog comment form (without any annoying Captcha or logic-puzzle stuff on it though!). They can drop us their email addresses and everything’s fine.

A bot on the other hand will see a form field that it does not understand and a regular email field. It thus will fill in the email field and immediately get caught in our before_filter.

Job done :-)

Further suggestions?

Leave a comment


  1. Roger said October 4th, 2007 at 12:07 AM  

    The “for” attributes in your “label” elements are incorrect. They should refer to the input element ids.

  2. Sven said October 4th, 2007 at 11:36 AM  

    Thanks for the catch, Roger! I’ve fixed that.

  3. Sven said December 8th, 2007 at 04:11 PM  

    testing the plugin on Rails 2.0 …

  4. Donovan Dillon said January 12th, 2008 at 07:10 AM  

    Hi Sven,

    Great site. Thanks for the excellent Mephisto plugins. Does the inverse captcha plugin work with Mephisto/Rails trunk? I just tried it with my Mephisto/Rails trunk installation and received 503 errors. I may be doing something wrong, but I want to ask before diving into serious/unnecessary troubleshooting. Best regards,

    Donovan Dillon.

  5. Carl Pelletier said January 12th, 2008 at 01:23 PM  

    Hi Sven, I tried it with Mephisto trunk and the I got problem too. The email catcha field not appear on every page. I can’t see it must of the time.

    Any idea why ?

    This is my code:

    {{ form.sneaky_email }}


  6. Carl Pelletier said January 12th, 2008 at 05:02 PM  

    I not use I understand, the problem is that the input field is never outputed. It like that the Plugins is never loaded.

    Can you give me some tips to debug the problem?

    Thanks again for your great work!

  7. Sven said January 15th, 2008 at 01:53 PM  

    Hi Carl,

    I suspect this might have to do with Rails’ weird behaviour of not reloading plugins in development mode. Did you try to run Mephisto in production mode? Does the same happen in production mode?

    If the problem persists please contact me by email and tell me your setup details. I’d very much appreciate to learn about how this stuff could possibly fail. (For me it works for almost a year now on several Mephisto versions.)

  8. Sven said January 15th, 2008 at 02:12 PM  

    Hi Donovan,

    I don’t know about Rails edge (somebody recently said that you must be crazy to run on Rails edge these days, I think it was Jamis? I guess the same might apply to Mephisto edge.)

    But I’m successfully running this on these versions: Rails 2.0.1 and Mephisto trunk rev 3066

    That said, a 503 error might result from Rails 2.0.2’s enhanced session secret stuff. In this case you’d find a note about that in your log file.

  9. Gaspard Bucher said March 3rd, 2008 at 10:13 PM  

    A cool idea would be to send the content of the spam-bot into a Bayesian anti-spam software like DSPAM for inoculation.

    The technique exists for emails (it’s called a honeypot). The spam-bot sends spam to the hidden email, inoculating the real email shown to real users. When the spam hits the real address, it is recognized as spam because of the inoculation. The only risk with this technique is clever bots feeding false information in the inoculation pipe.

    The “Negative captcha” technique will work as long as it is not too famous… Or as long as it is adapted on each site (different form ids/names).

    Anyway, thanks for the simple but elegant idea to fool these ugly machines visiting our pretty pages.

  10. Sven said March 3rd, 2008 at 11:01 PM  

    Hi Gaspard!

    Actually since I’ve installed this technique on my blog I’ve seen no more than four spammy comments show up in my admin interface. :)

    I’m no expert in these things. But I’d guess that there always (or at least for a long time to come) will be a good portion of “super-stupid bots” that just look for open comment forms and drop their stuff. Why? Because they are so cheap. Today there are bot that can do all kind of trickery … but they will also (always?) require significantly more resources to run.

    So, looking from this perspective, this negative captcha technique surely never will solve the whole spam problem (at all) but it can be useful as an “outer floodgate” where the stupid 98% can be easily sorted out. The rest then can be picked up by Akismet and others.

    Anyways … I’m just super-happy with not having to deal with blog spam :D

  11. MaD said March 28th, 2008 at 11:28 AM  

    Hi Sven, Thanks for your plugin! I implemented it on our website’s blog (running Rails rev. 8648 and Mephisto rev. 3091).

    [FYI:] In order to get it up and running I had to change the following:
    In inverse_captcha.rb I commented out the line:

    include_into 'MephistoController'
    Instead I put into MephistoController:
    include InverseCaptcha::MephistoController
    Hope this helps. Regards Dominik PS @Gaspard: If you want to have changing ids/names everytime a page is displayed. just edit inverse_captcha.rb like this:
    salt = (1..16).collect { 
      (i = Kernel.rand(62); 
      i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr 
    name.to_s.crypt(salt).downcase.gsub(/[^a-z]*/, '') 
  12. spectra said April 27th, 2008 at 01:45 AM  


    Running Rails 2.0.2 and Mephisto 0.8, it doesn’t work. The fields form.sneakyemailcodename and form.sneaky_email are not available to templates…

    Any idea of what might be going on?

  13. Sven said May 11th, 2008 at 03:43 PM  

    Hi MaD,

    thanks for those tips. It’s good to know that that workaround would work.

    Hi Spectra,

    I’ve just committed a fix for the liquid tag registration process. I hope that finally fixes these issues. It works fine for me locally in both dev and production modes.

    Please let me know if that helps.

    Sorry for the long delay, folks :)

  14. m3talc0re said May 16th, 2008 at 04:32 PM  

    Good idea, so long as the bots are fixed to cope with this. Anyway, you should change the display: none; to width: 0; height: 0; for accessibility’s sake. Not to mention it’d be easier for bots to be fixed to ignore display: none; than it probably would for them to ignore width and heights.

  15. xxcemil said May 31st, 2008 at 11:15 PM  

    about css parameters

  16. PunNeng said June 5th, 2008 at 02:28 PM  

    Thank you Sven.
    It works well.
    It’s damn cool and really simple.

  17. tamiflu said June 7th, 2009 at 11:59 AM  

    Thank you Sven. Good work. It is a good idea

  18. online casino craps said June 10th, 2009 at 11:47 AM  

    The idea is good, I think that if you hide everything right in the CSS few bots will be able to work arround. Also you can change name of fields or play with name of variables and them content, and just to ve sure to avoid bots I would add captcha images per subject where you show to the user N images which N-1 are connected with one subject and only one is not connected to that subject, the question is to ask to the user which is the main subject. Also I have seen already some test that you can do to a human to prove is really a human, including captchas that check you are an adult and not a child.

  19. Rolf said May 20th, 2010 at 05:43 PM  

    Yes, works great indeed ! Thanks, Sven ! Hope to use it again in a near future :)

  20. internet fax said June 19th, 2010 at 01:49 PM  


    Hey great site and the plug-in related issue is also great!

    Thanks, Peter

  21. Tanguy S. said November 12th, 2010 at 02:42 PM  

    I use the same thing to prevent my forms to be spammed and it works well.

    But I do it simplier, I just put a hidden input which name is email and it seems that bots fullfill it, so I know if it is spam or not.

  22. anokhi said January 18th, 2011 at 10:05 PM  

    Well, the article is in reality the top-quality on this exemplary theme. I accord with your decisions and will thirstily look forward to your following updates. Only telling thanks will not just be adequate, for the great limpidity in your writing. I will now grab your rss feed to continue informed of any updates. Delicious work and much success in your business relations. VW Turbo

  23. jack said January 23rd, 2011 at 11:18 AM  

    I have installed this plugin and its working fine for me, but I am have some issue when passing extra parameters in params, not getting other params parameter with the links (getting only page ) cheap vps

  24. anoki said February 3rd, 2011 at 04:06 PM  

    Well, the article is in reality the top-quality on this exemplary theme.Property Finder I accord with your decisions and will thirstily look forward to your following updates. Only telling thanks will not just be adequate, for the great limpidity in your writing. I will now grab your rss feed to continue informed of any updates. Delicious work and much success in your business relations.

  25. QQQ said February 7th, 2011 at 06:31 PM  

    Finally we kissed and the passion scale went sky high and I knew I was onto a good thing - sex was a certainty free porn videos. She never hesitated when I began to fondle her breasts and she willingly exposed them for me mobile porn. They were firm and I suspected a breast enhancement but said nothing - they still felt good and I was enjoying them and gradually working my way further south free porn tube. She was a step ahead of me and before I could completely undress her she moved on me atk hairy and I was suddenly having my pants pulled down and I was enjoying one of he best cock sucking hairy pussy experiences I had ever had. ABB728019394

  26. muneeb said February 24th, 2011 at 01:35 PM  

    I accord with your decisions and will thirstily look forward to your following updates. Only telling thanks will not just be adequate, for the great limpidity in your writing. I will now grab your rss feed to continue informed of any updates. Delicious work and much success in your business relations.Go Ped

  27. Kat said February 28th, 2011 at 08:42 AM  

    Keeping spam off my family site is an ongoing project.

  28. fake tattoos said March 21st, 2011 at 08:35 AM  

    It was a beneficial workout for me to go through your webpage. It definitely stretches the limits with the mind when you go through very good info and make an effort to interpret it properly

  29. chat said March 31st, 2011 at 07:17 PM  

    This will fix the spam technique problem:

    Dependencies.loadoncepaths -={|path| \ path =~ %r(^#{File.dirname(FILE)}) }

  30. side sleeper pillow said April 22nd, 2011 at 07:06 AM  

    Nicely written article, Knowledgeable and informative post. I’m really glad I came my way along your site. Keep posting, I really like the whole topic. Thanks for sharing.

  31. Micha said May 11th, 2011 at 10:44 PM  

    I have the Captcha on some of my Sexseiten and I like to say, its work. But not at all Porno. Dosn’t matter - it is a good think and a must have by Forms

  32. Okey oyunu said May 12th, 2011 at 03:52 PM  

    Tüm dünya artik okey oyunu oynuyor. Yillardir bir çok oyun programi olmasina ragmen, içlerinden en güzeli olarak nitelendirebilecegimiz tek bir site göze çarpmaktadir. Diger tüm okey oyunu programlarinin aksine ücretsiz olmasi ve 3 boyutlu olarak hizmet vermesi mükemmel bir gelismedir. Sizlerde adresinden bu essiz okey oyununu indirebilirsiniz. Kullanimi çok basit ve Türkçe dil seçenegi ile kolaylikla oyuna baslayabilirsiniz. Ister kendi ülkenizden, isterseniz dünyanin tüm farkli bölgelerinden dilediginiz oyun odalarini seçerek, oyuna hemen baslayabilirsiniz. Okey oyunu oynamak için artik arkadas bile aramaniza gerek kalmadan, bilgisayarinizdan 100 binlerce üye ile online olarak okey oyununu oynamanin zevkine varabilirsiniz.

  33. Chung22 said May 20th, 2011 at 07:50 AM  

    It is nice to find a site about my interest. My first visit to your site is been a big help. pass4sure 1z0-536 Thank you for the efforts you been putting on making your site such an interesting and informative place to browse through. pass4sure 642-072 I’ll be visiting your site again to gather some more valuable information. pass4sure 642-467 You truly did a good job.

  34. porno said May 22nd, 2011 at 01:33 PM  

    I do agree with all of the ideas you have presented in your post. They’re really convincing and will definitely work. Still, the posts are too short for newbies. Could you please extend them a bit from next time? Thanks for the post.

  35. porno said May 22nd, 2011 at 02:20 PM  

    good comment. thanks you friends.

    I’ve surfed the net more than three hours today, however, I haven’t found such useful information. Thanks a lot, it is really useful to me

Sorry, comments are closed for this article.

artweb design
Sven Fuchs
Grünberger Str. 65
10245 Berlin, Germany

Fon +49 (30) 47 98 69 96
Fax +49 (30) 47 98 69 97