Abhijit Speaks :

On Life, Technology, Stocks and Movies

RA-captcha – An idea for ajax based captcha for rails applications.

with 5 comments

While working on a new feature for paahijen-Scratchpad, we needed a captcha mechanism to keep the spam-bots out of the door! Since some of our users may not be quite comfortable with typing convoluted roman alphabets, we needed a different system. Honestly, I was too lazy to try out all the Rimage giri to get something useful and somehow wanted a mechanism, which is lightweight, easy to implement (lesser code, no new learning.. ;-) ). Somewhere, I had read about “arithmetic” captcha, and we decided to use it. We just hit upon an interesting idea… to use Ajax for captcha.. Hence the name RA-captcha (rails ajax captcha)..

The idea is fairly simple.. What it basically does is uses link_to_remote to update the contents of a “div” in the form dynamically with a text for a simple arithmetic equation. The equations is so simple that a 5th grade average student can do them without troubles.. eg. the equation will be something like “8 + 2 = ” and then an input text box is provided to enter the value.. Though this technique uses "link_to_remote", it is not too hard to use other ajax methods for the rails as the need be!

Here is a simple code that explains the idea… The code is not perfect and I am not a rails expert, Also it doesn’t do any validations than minimum.

Create an application “ajax-test” using rails ajax-test

We are going to add a controller called “main” controller and corresponding views. For this example we don’t need any ActiveRecord models.

script/generate  controller main

We are going to create the view for this controller and action “index”. No layouts..
So create a directory called main inside app/controllers and edit the file
app/views/main/index.rhtml with following contents.

<h4> "Element.show('test-form');", :url => { :action => "getequ" }, :update => "equdiv" }) %> </h4> <div id="test-form"> "submit_test"}, {:id => "t_form"}) %> "20x10" %> <p><b>Humans? Please do some simple Math! <div id="equdiv"> </div><input type="text" name="capval" size="2" /> </b> </p> </div> <script> Element.hide("test-form");</script>

The controller code looks like this…..

class MainController < ApplicationController def index end def getequ numbers = (0..9).to_a @equ = '' num1 = numbers[rand(numbers.length - 1)] num2 = numbers[rand(numbers.length - 1)] session[:capsum] = num1 + num2 @equ << num1.to_s + " + " + num2.to_s + " = " render(:inline => @equ, :layout => false) end def submit_test if request.post? if params[:capval].to_i == session[:capsum] @userdata = params[:userinput] flash[:notice] = "your input is accepted!!" else flash[:notice] = "Sorry you got the math wrong! can't accept your input!" end end # reset the sum so one cannot simply press 'back' buttton and re-use it!! session[:capsum] = -100 end end

There is an additional view defined for submit_post. Which looks like this…

<b> #{flash[:notice]} </b> </p>" %> <p> "index" %> No input data click "index" %> to start.

How this works is fairly simple. Basically, whenever the first link is clicked an action in the controller called getequ is called, which generates the equation string for us and stores the value for the equation in the session[:capsum] variable. When the form is subimtted, the value of the text field is checked agains the value stored in the session[:capsum] variable. If the values match, the input is allowed, if they don’t match the input is not allowed and the view for submit_test is rendered accordingly..

Since, the value the user has to input is only available upon loading the page and updating div, this value simply will never be known to spam-bot to be used without actually loading the page..

———

The idea looked so simple to me and pilot to be overlooked for so loong. May be there is a catch which I am not getting yet!! Hopefully someone will point out….

PS: Editing html on blogger is a big pain!! eg. it gets rendered. One way out is to change the “<” of each html tag with “&lt;” and then blogger doesn’t try to render it…..

Written by gabhijit

June 18, 2007 at 2:32 pm

5 Responses

Subscribe to comments with RSS.

  1. Hi Abhijit,

    Very interesting idea.

    How is the “session[:capsum]” variable stored?

    I can tell you one thing, that I have done recently – is to scrape the dynamic parts of a DHTML web pages (using PHP and curl). Basically we read the parts of a web page (div’s) that are dynamically populated using Javascript or XHR (using innerHTML). So, it is possible to read dynamically populated DOM variables, I am sure session variables too. So, in that case it may be possible to scrape the left-hand-side of the equation, therefore calculate this equation and therefore break the captcha.

    Even with this will still be a captcha, however a weak captcha. I have seen several captcha implementations, some are very strong, to an extent that a lazy human (like me) would find it objectionable to read the text and type it in the form. I have seen weak captcha, where they just have a handmade textual pattern that you need to guess.

    My suggestion will be, unless you are a target of a major DOS attack, you shouldn’t spend much time on a captcha, just fabricate a few dozen images and use those. Or if the above implementation is easy enough, just use that.

    I hope that helps.

    Thanks,
    Mukul.
    http://mukulblog.blogspot.com

    Mukul Kumar

    June 19, 2007 at 10:09 am

  2. Hi Mukul,

    Session variables are stored on server, in memory or in the db. I don’t think one can find out the LHS of the captcha equation Abhijit is talking about.

    So, If the bot is intelligent enough, it can read the dynamically populated equation but not the answer.

    Thanks,
    Siddharth

    Siddharth

    June 19, 2007 at 10:59 am

  3. Hey this idea has been implemented. It’s good – but once spambots find out about this, I dont think it should be a challenge to screenscrape equations and then spam. check out the blogs.sun.com/abhishekn

    Sun blogs are using this, and AFAIK a lots of others too. Its a very viable lightweight CAPTCHA system.

    Abhishek

    June 22, 2007 at 8:22 am

  4. Abhishek,

    The idea is not about equations ie. arithmetic, the idea is about generating div content dynamically which the spambots cannot get easily unless they somehow read the contents of the div also… (which is somewhat harder without XHR).. Having said this.. it does not mean that this is not hard to read the equations at all, it is just about increasing the “cost” for the spambots!

    Abhijit

    June 22, 2007 at 6:18 pm

  5. Just out of curiousity, I was checking the implemntation of the equation for CAPTCHA on blogs.sun.com . Unfortunately, it generates the same equation evertime… I should say pretty lame???

    Abhijit

    June 22, 2007 at 6:30 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.