It’s no secret that I hate Captchas, I find them to have a negative effect on any web application user experience.
We have had lots of user complaining about Captcha’s (we used multiple ones) difficulties in one of customer facing applications. I have blogged before about using a HoneyPot Captcha technique using asp.net MVC but the application in question is built on Webforms.
Our solution was to build a HoneyPot Captcha httpModule and plug in while the application running.
These are the steps we have taken to successfully replace the Captcha controls with this module
- Add an ASP.NET Text control to the pages where needed to have the implementation (using HTML markup, no code behind)
<asp:TextBox ID="name" runat="server"></asp:TextBox>
<asp:TextBox ID="email" runat="server"></asp:TextBox>
<asp:TextBox ID="phone" runat="server"></asp:TextBox>
<asp:TextBox ID="URL" runat="server" CssClass="capcha"></asp:TextBox>
<asp:Button runat="server" ID="submit" Text="Submit" />
The Text control with ID="URL" is our captcha control
- Create a CSS class to avoid confusing screen readers
/*Rename this class to avoid bots discovering the honeypot*/
.capcha
{
display :none;
speak: none;
}
}
speak psudo is set to none to avoid having screen reader announce the control to visually impaired users
- Create the module
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ModuleBasedCaptcha
{
public class Capcha : IHttpModule
{
#region IHttpModule Members
const string CAPCHACONTROLNAME = "URL";
public void Dispose()
{
//clean-up code here.
}
public void Init(HttpApplication context)
{
context.BeginRequest += ((object sender, EventArgs e) =>
{
var app = sender as HttpApplication;
if (app != null && app.Request.HttpMethod == "POST")
{
var request = app.Request;
var val = request.Form.GetControlValue(CAPCHACONTROLNAME);
if (!string.IsNullOrEmpty(val))
{
context.Response.End();
}
}
});
}
#endregion
}
}
Here we instruct the module will only handle POST methods, the GetControlValue is an extension method I have created to get the value from the asp.net controls without having to use the full server name (ctl00$MainContent$URL)
- Wire the module in the web.config
<system.webServer>
<modules>
<add name="HoneyBotCapcha" preCondition="managedHandler" type="ModuleBasedCaptcha.Capcha,ModuleBasedCaptcha"/>
</modules>
</system.webServer>
Since we are using IIS 7, we only needed to set the module up under system.webserver note (for IIS 6 you have to setup the module under system.web)
Since this modification, we have zero spam registrations and zero customer complaints :-)