HoneyPot Captcha using an Http Module

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

  1. Add an ASP.NET Text control to the pages where needed to have the implementation (using HTML markup, no code behind)
  2. <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

  3. Create a CSS class to avoid confusing screen readers
  4.  /*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

  5. Create the module
  6. 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)

  7. Wire the module in the web.config
  8.  <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 :-)

Add comment