Saturday, October 27, 2007

Using unobtrusive javascript as a captcha

I have been reading and thinking about Captcha's lately. Captcha's are a frequently used way to tell humans and computers apart. It's main use is in preventing robots access to certain parts of the site, the registration section for example, or the comments sections of articles.

Current captcha's have some problems

Current captcha's have some serious disadvantages:
* They can completely lock out disabled users
* They can be to difficult to solve for humans in some occasions
* They can be beaten by sufficiently intelligent AI
* They can be a lot of work to create (logic/puzzle-based captcha's)
* They are obtrusive

Most of these problems can be solved to some degree with traditional image, audio or logic/puzzle based captcha's. You can provide for an audio captcha as an alternative to an image-based captcha to greatly improve accessibility to the visually impaired, as proposed by Standards Schmandards (and in use on lots of sites already). You can tweak with saturation, noise and deformation of the images and audio samples used to maximize ease of use for people and minimize robots abilities to pass the test, but the last problem remains.

They are so darn obtrusive. I myself completely understand what they are for and still find them annoying! Especially the difficult to solve ones, which make me feel I have to take an IQ test before being allowed to register. So how will people feel about them that don't understand or care why it is even necessary?

I have been coming up with an alternative to captcha's that could potentially solve the last problem while retaining the advantages of Captcha's, the ability to filter out form posts done by robots instead of legitimate human users.

A solution?

My solution works as a layer above the traditional captcha's. And being on this blog, its obviously based on Javascript. It works on the premise that real humans have to type in the message they want to post, like real humans do. Recent research suggests that each person has unique typing characteristics that might even be used as identification

Here is how I think it might work in practice.
Below the form fields, but just above the submit button, are a traditional image and audio based captcha, as a fallback option for clients that have no javascript. The form itself is marked with a class, for example 'captcha', that triggers an unobtrusive piece of javascript, to attach itself to the form and hide the traditional captcha's. As the user fills in the form, metadata is captured on the process of filling in the form. What time did the first character got entered into some form field (process-start)? What time did it get submitted (process-end)? How many characters entered (determines avg. typing speed), biggest and shortest interval between keystrokes etc etc. On form submit, the captured data would be inserted into an extra hidden field and posted to the server along with the rest of the form. The captured data would be analysed on the server for anomalies and suspect posts would be rejected.

Ofcourse, this could trigger an arms race again, but this time, we don't have to force the user to jump through any hoops. Instead, we have to capture more and better metadata while the spammers have to get better and better at emulating real user's typing characteristics. .

I'm still playing with this idea in my head. The basic implementation is not that difficult to build, but the typing characteristics analysis seems difficult. Any ideas?


Jorick de Lange said...

Interesting theory. It’s too late for me to think straight, but I’ll keep this in mind. There should be a solution in the theory you just described. Only how… I think you’re going the right way when there should be a match between the average speed of typing and the submit time. There’s only one small obstruction: what to do with the people who only wants to submit a smiley? Their ‘average speed’ is just that fast of a spambot, ‘cause their only thing to do is to click, or type, a smiley… Maybe, that's where a traditional 'captcha' comes in? One invisible control, and a visible control, just to check whether a submit has been submitted by human or spambots... :)

AlBundy said...

But what if you fill in a form as a human and then analyze the data that's submitted. You could find out what string is submitted in the hidden field and use that string for your spambot, right? Of course, you could check for duplicate entries, but then people who coïncidentally have the same average typing speed, submit time, etc. could get a false positive, so you would have to clear the buffer once every x hours.
Second, when there's a check for duplicate entries, it will be possible, by brute force, to find out what the bounday values of the hidden string are before they get rejected, and then let the spambot generate some random value between the boundaries. Even an IP-ban could be worked around by using a botnet.

Unless I misunderstood the whole article, this is not too hard to code, the whole process of trial and error, scripting and testing the code could be done in not more than a day.

Stijn said...

Preventing replay attacks (where the spammer just captures his own typing data for example) is probably going to be difficult. Maybe a good solution would be feeding the typing meta-data to the host website interactively, as the user is typing, using AJAX. That would probably be harder to replay for bots.

if the recorded typing meta-data is comprehensive enough, a bot probably won't be getting away with just generating random typing meta-data within some boundaries. I think that it could prove difficult for bots to emulate human typing. It all depends on the analysis algorithm that interprets the meta data I guess.

I've been playing around with this idea but am not sure yet how to prevent replay attacks, if it's at all possible to prevent them.