views:

211

answers:

3

We use Captcha control in a registration form that we make full client validation for all fields in JavaScript ( JQuery ) beside server validation ..

I tried a lot of ways but all will write the Captcha value in JavaScript that can be accessed by anyone :(

I search if is there any way that allow me validate Captcha value in client side using JQuery in secure way or it can't be done ?

+6  A: 

It cannot be done.

Javascript is client-side, as you know, and any code client-side has to be treated as potentially compromised as you don't have control over it.

At best, you could resort to sending up a salted hash of the value along with the salt, but even that in itself could be used to test guess values before actually submitting it.

Everything else relies on calls to the server.


As per comment request, here's the general idea:

Firstly, on the server, calculate a random string to be used as the salt. This should be roughly unique every request. The purpose of this string is to prevent rainbow table attacks.

Now, saving this string separately, but also create another string that is the concatenation of random string and the Captcha answer. Of this new combined string you generate the hash (for example, SHA-1) of it.

using System.Web.Security;
...
string hashVal = FormsAuthentication.HashPasswordForStoringInConfigFile(combined, "SHA1");

Both the random string and the hash value need to be placed in the page for the javascript to be able to read.

On the client side, when a user answers the Captcha, take the random string and concatenate it with the answer (getting the idea here?). Taking this string, you can use something like the SHA-1 JQuery plugin to hash it and compare it with the pre-computed hash you sent up.

hashVal = $.sha1(combinedString)

If it matches, it is (almost) certainly the correct answer. If it doesn't, then it is 100% the wrong answer.

Dan McGrath
Dan could you please give me example of 'salted hash solution' ?
Space Cracker
Actually you can use hashing to not expose the captcha value, but still enable client side validation. This is of course only for responsive UI, and has to be checked at the server also.
Dykam
By revealing the hash value it enables the attacker to make multiple guesses without sending it to the server. Also, if it cannot get a correct guess it can then refresh the page. This can enable the attacker to have a much better strike rate with a lower detection rate.
Dan McGrath
@Dykam If the gain is "only for responsive UI" in the captcha screen, it seems that revealing anything that could help the attacker is too much weight on the other side
belisarius
If you use some sha hashing method the hackers better use captcha crackers, as rainbow tables are not very usable for sha as both the table would be way to big.
Dykam
+1  A: 

you could use ajax to post the current value to the server, which would respond true or false. that would keep you from doing a real post and also from giving away the catpcha's value in html.

nathan gonzalez
Unfortunately, we won't user ajax to make server validation in a hidden way so we search for some other solution in JQuery ..
Space Cracker
i think i'll have to agree with dan then. without exposing the answer in your script or html there is no reasonable way to do this.
nathan gonzalez
There is no solution in JQuery alone. Only server access will give you peace of mind.
Amadan
A: 

My solution )) Every time when page shows captcha to the user, you can dynamically generate obfuscated JavaScript functions(i think the best way 5 or 10). For example, one function(or 3)) ) can set cookies with pregenerated hash(server returns it)(from real value of the captcha), other functions must realize server side algorithm to check value which user's typed. I can say that it works for 100%, because it is very hard to parse dynamically javascript + we set user cookies on client side(It is very hard for Bots's to find out where and how you set and check cookies), by using JavaScript.

Saff
sorry Saff , but could you give me more explain about your solution
Space Cracker
You have server side simple hash for capcha: md5(captcha_srv_side)We need to match this hash with hash on clientside.The simplest way is to split on 2 parts our hash and write it to user cookie by server side({"v1":"81b..","v2":"873f..."}).Now we've got 2 vars in user cookies.We can write very complicated code using a lot of functions of javascript, then obfuscate this code.When user enteres captcha, script will run js event function,which concat 2 vars(v1,v2), generate md5 from user string,write it to cookies and then match them.It's just little example. There are many variations.
Saff