Sometimes you may want to protect certain functionality from being used by automated tools. One way of preventing this from happening is using a CAPTCHA, which is basically an image that is intended to be impossible to read by software (e.g. OCR) but possible to read by humans. The Wikipedia article is a good starting point with regards to the limitations of a CAPTCHA and suggestions for how to address those limitations.
In this post I’d like to show to you how you could integrate a simple CAPTCHA mechanism for ASP.NET MVC 2 using C#. My objectives for this implementation were:
- Ideally all CAPTCHA related code is located in a single class.
- Using the CAPTCHA in a view should be a single tag.
- Avoid having to register HTTP handlers or any other modification of the web.config file
Having all of that in mind I experimented a while, tried out a number of suggestions that I found on the web and settled for now with the one I’ll describe in this post.
I’ll start with how the CAPTCHA can be used in a view (for MVC newbies: roughly speaking this is MVC-lingo for page or form). In essence the solution uses a controller class named CaptchaController implementing a method Show(). In your view you use it like this:
Next to it, you probably would want to display a text box for the user to enter their reading of the CAPTCHA value, so in the view the markup for that would look as follows:
This will create an image and next to it you would display a text box as follows:
Of course the value in the image would change.
Now that we can display the CAPTCHA and also have a text box for the user to enter the CAPTCHA value, the next challenge is to store the CAPTCHA value somewhere so that once the user has entered the value and it is coming back to the server, some server side code can validate the CAPTCHA value. The server side code for this looks like this:
This method returns a boolean that you can then use for further processing.
All the rest happens behind the scenes and is completely handled by the class CaptchaController. So what follows is a description of the implementation.
When the CaptchaController renders an image it also creates a cryptographic hash as a session variable. This hash is an MD5 value in my implementation and the calculation uses an additional value to add some ‘salt’ before calculating the MD5 hash. Since the client has no access to the server side code it won’t be able to calculate a matching pair of MD5 and CAPTCHA value. As ‘salt’ I use the assembly’s full name which changes with each compile as it includes the version number.
And here is the source code for CaptchaController:
As always: If you find any bugs in this source code please let me know. And if you can think of other improvements I’d be interested, too.
In closing I’d like to mention reCAPTCHA, for which an ASP.NET component is available as well. Google is the owner of reCAPTCHA and uses it to correct mistakes due to the limitations of OCR (Optical Character Recognition) in their book scanning activities. Depending on your requirements reCAPTCHA might be a good solution as well in particular if you are seeking better protection and/or want to support visually impaired users.
Maybe one day I’ll have the time to look for a single tag / single class integration of reCAPTCHA for ASP.NET MVC …
Excellent! This article really helped me! It is both effective and ingeniously simple!
ReplyDeletehi, i am new to MVC. How would i implement your code in the registration view?
ReplyDeleteHi ,
ReplyDeleteI am getting error on(m.CaptchaValue) while writing on view on every label,text-box, validation control. I am using asp.netMVC 2.0.
Please help me out. does it work when i deploy it on server?
Thanks
i am unable to get image while i deploy on iis7.
ReplyDeleteThank you for this elegant solution to solve the human verification in MVC webapplications!
ReplyDeleteHi, this is an excellent work! What about the license?
ReplyDelete@Anonymous: My code in this post is provided "as-is", use at your own risk. All other code is subject to the licensing conditions of their respective owners.
ReplyDeleteThis works locally but when I deploy I get a red x for the image. Any ideas?
ReplyDeleteIs the complete code available for download?
ReplyDeleteThanks
@Anonymous Unfortunately the source code is part of a commercial project so I cannot make the entire source code available. However, if you have some experience with ASP.NET MVC it shouldn't be too difficult to get it working. Good luck!
ReplyDeleteUltimate example ! It works for me I have searched lots of captcha codes but this one is the perfect.
ReplyDeleteThanks.
Hi Thanks!!!
ReplyDeleteBut I cann't run my solution, I don't know if you coult give an example please my email is kalu_rf@gmail.com
@kalu_rf Unfortunately this would be a significant effort so would be beyond this blog post. The project that this is part of is a commercial project so I cannot share the entire source code either for confidentiality reasons.
ReplyDeleteI have a problem, my captcha dont reloading in all browsers except chrome, becouse i think something with cache.. Any ideas ?
ReplyDeleteThank you so much for sharing. This is really excellent. :)
ReplyDelete