A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Henrik Buer
May 16, 2011
  9977
(1 votes)

XForm spam prevention with reCAPTCHA or jQuery slider

Surprisingly few of my customers has reported problems with spam in their XForms but some have. This blog post is an exercise in how this issue can be addressed. There are a lot of methods for protecting spam in forms, logins, forums etc. Some of the most widely used are captchas or some logical puzzle, basically any method that automated spam bots has a hard time solving but humans solves easily is used. 

reCAPTCHA

I’ve decided to do two different methods. The first is integration of reCAPTCHA in XForm. Here’s an example how it can look like with reCAPTCHAS “clean” theme.

treCAPTCHA

This is the XForm from the Public templates. To do this I’ve hooked in to the ControlsCreated event of the XFormControl on the page. There I create a new control of type RecaptchaControl and add this to the XFormControl above the submit button. Download the reCAPTCHA ASP.NET library (it’s just a dll). Drop it in your bin folder and add a reference to the dll. Heres the ControlsCreated event handler.

   1: protected void FormControl_ControlsCreated(object sender, EventArgs e)
   2: {
   3:     Recaptcha.RecaptchaControl objReCaptcha = new Recaptcha.RecaptchaControl();
   4:  
   5:     objReCaptcha.ID = "MyReCaptcha";
   6:     objReCaptcha.Theme = "clean";
   7:     objReCaptcha.PrivateKey = "your_private_key_here";
   8:     objReCaptcha.PublicKey = "your_public_key_here";
   9:  
  10:     // Find submit button and insert captcha before
  11:     foreach(Control objControl in FormControl.Controls)
  12:     {
  13:         if (objControl.GetType() == typeof(EPiServer.XForms.WebControls.Submit))
  14:         {
  15:             FormControl.Controls.AddAt(FormControl.Controls.IndexOf(objControl), objReCaptcha);
  16:             break;
  17:         }
  18:     }
  19: }

After this you need to validate the reCAPTCHA when the form submits. This is done in BeforeSubmitPostedData event handler.

   1: protected void FormControl_BeforeSubmitPostedData(object sender, EPiServer.XForms.WebControls.SaveFormDataEventArgs e)
   2: {
   3:     Recaptcha.RecaptchaControl objControl = FormControl.FindControl("MyReCaptcha") as Recaptcha.RecaptchaControl;
   4:  
   5:     if (objControl != null)
   6:     {
   7:         Page.Validate();
   8:  
   9:         if (!objControl.IsValid)
  10:         {
  11:             // TODO: Notify user that validation failed
  12:             e.CancelSubmit = true;
  13:         }
  14:     }
  15: }

That’s it. Add a custom validator or some other kind of user feedback if validation fails…

jQuery slider

With that said I must admit… I hate captchas. I think it’s an intrusive way that hinders user interaction. I’ve also seen a lot of bad captchas that’s barely readable which I find annoying. Your users deserves better.

My humble approach to spam prevention without pissing off my users are to use a jQuery slider instead of a button. Here’s how it can look.

Slider

The idea here is that spam bots can’t interact with the slider. Help me out here readers… is this true? This demands just slightly more effort from the users compared to clicking a button.

I add the slider like I did the reCAPTCHA with the difference that I also hide the submit button. If you want to use the options that the editor can set for the forms submit button (ChannelOptions, mail addresses and subject) when the slider does postback, this is the place to do it. See the code below.

   1: protected void FormControl_ControlsCreated(object sender, EventArgs e)
   2: {
   3:     Slider.Slider objSlider = new Slider.Slider(Page.ClientScript.GetPostBackEventReference(this, Slider.Slider.PostBackArgument));
   4:  
   5:     objSlider.SliderHeading = "Vote by sliding me to the right...";
   6:     objSlider.SliderStyle = "style=\"margin-left:5px;margin-top:5px\"";
   7:  
   8:     // Find submit button, hide it and add slider
   9:     foreach(Control objControl in FormControl.Controls)
  10:     {
  11:         if (objControl.GetType() == typeof(EPiServer.XForms.WebControls.Submit))
  12:         {
  13:             // Save ChannelOption for later use when slider does postback
  14:             EPiServer.XForms.WebControls.Submit xSubmit = (EPiServer.XForms.WebControls.Submit)objControl;
  15:  
  16:             SubmitOptions = ActionToChanelOptions(xSubmit.Action);
  17:             FormControl.Data.MailFrom = xSubmit.ActionSettings["from"];
  18:             FormControl.Data.MailTo = xSubmit.ActionSettings["to"];
  19:             FormControl.Data.MailSubject = xSubmit.ActionSettings["subject"];
  20:  
  21:             if (SubmitOptions == ChannelOptions.CustomUrl)
  22:             {
  23:                 FormControl.Data.CustomUrl = xSubmit.Action;
  24:             }
  25:  
  26:             if ((FormControl.Data.MailSubject == null) || (FormControl.Data.MailSubject.Length == 0))
  27:             {
  28:                 FormControl.Data.MailSubject = FormControl.FormDefinition.MailSubject;
  29:             }
  30:  
  31:             Int32 iIndex = FormControl.Controls.IndexOf(objControl);
  32:  
  33:             FormControl.Controls[iIndex].Visible = false;
  34:             FormControl.Controls.AddAt(iIndex, objSlider);
  35:  
  36:             break;
  37:         }
  38:     }
  39: }
I’ve implemented the slider the same way that the reCAPTCHA is implemented – as a class inheriting from System.Web.UI.WebControls.WebControl. There I override the Render() and RenderContents() methods (link to source at the end of this blog post). Note that in order to get the slider to postback you’ll have to provide a postback string. This can be obtained from Page.ClientScript.GetPostBackEventReference(). To check if the slider is postbacking I do this in Page_Load()
   1: if (IsPostBack && Request["__EVENTARGUMENT"] != null && Request["__EVENTARGUMENT"] == Slider.Slider.PostBackArgument)
   2: {
   3:     Page.Validate();
   4:  
   5:     if (!Page.IsValid)
   6:     {
   7:         // TODO: Notify user that validation failed
   8:     }
   9:     else
  10:     {
  11:         FormControl.SubmitForm(SubmitOptions);
  12:     }
  13: }

I’d really like your opinion on using a jQuery slider as spam prevention. Does it stop spam bots? Is there any other way for a bot to interact with a slider besides simulating mouse movements and clicks? I’ve been running the slider variant on my public site “protecting” blog comments and a guestbook for a few months now. So far no spam… Feel free to post your thoughts on the effectiveness of having a slider as opposed to having a captcha.

Code ‘n links

reCAPTCHA – get your keys here

reCAPTCHA ASP.NET library – get your dll here

The code is the XFom template from the Public templates modified to reside in an .aspx file

XForm reCAPTCHA here

XForm Slider here

Slider.cs here

May 16, 2011

Comments

Anders Hattestad
Anders Hattestad May 16, 2011 09:31 AM

cool, thx for the post.

May 16, 2011 12:37 PM

The bot can't interact with the slider, that's true. But it can select one radiobutton, depending on the bots capabilities, e.g. supports javascript.

I recommend http://akismet.com/, which doesn´t require any user input at all.

Henrik Buer
Henrik Buer May 17, 2011 07:49 AM

Hi Johan

Interesting link. My reflection was that Akismet is most suited for comments/forum/guestbook and other forms that has a fixed field set. XForm can, as we know, vary but I see no problem filtering out the textboxes in a form and checking these with Akismet. My main concern is giving the editor the ability to report spam/ham back to Akismat. That is somewhat troublesome with EPiServer XForms. Another concern I have is the low (93%) blocking of all comment spam, trackback spam and pingback spam that is claimed http://www.codeplex.com/wikipage?ProjectName=AkismetApi

May 20, 2011 02:16 PM

I think 93% blocking is OK. Especially when considering that there is no need for user input.
There should be no problem to contruct a "blog comment" out of an xform posting. We use this method on our clients websites with great result.
CAPTCHAS is terrible from an accessibility standpoint and can also be a problem on other devices.

Jan 24, 2014 02:25 PM

@ Johan Ptersson,
Hi Johan,
Can you share a link to a webpage where you have implemented Askimet
I would like to see in the results in the front end

Please login to comment.
Latest blogs
Looking back at Optimizely in 2025

Explore Optimizely's architectural shift in 2025, which removed coordination cost through a unified execution loop. Learn how agentic Opal AI and...

Andy Blyth | Dec 17, 2025 |

Cleaning Up Content Graph Webhooks in PaaS CMS: Scheduled Job

The Problem Bit of a niche issue, but we are building a headless solution where the presentation layer is hosted on Netlify, when in a regular...

Minesh Shah (Netcel) | Dec 17, 2025

A day in the life of an Optimizely OMVP - OptiGraphExtensions v2.0: Enhanced Search Control with Language Support and Synonym Slots

Supercharge your Optimizely Graph search experience with powerful new features for multilingual sites and fine-grained search tuning. As search...

Graham Carr | Dec 16, 2025

A day in the life of an Optimizely OMVP - Optimizely Opal: Specialized Agents, Workflows, and Tools Explained

The AI landscape in digital experience platforms has shifted dramatically. At Opticon 2025, Optimizely unveiled the next evolution of Optimizely Op...

Graham Carr | Dec 16, 2025

Optimizely CMS - Learning by Doing: EP09 - Create Hero, Breadcrumb's and Integrate SEO : Demo

  Episode 9  is Live!! The latest installment of my  Learning by Doing: Build Series  on  Optimizely Episode 9 CMS 12  is now available on YouTube!...

Ratish | Dec 15, 2025 |

Building simple Opal tools for product search and content creation

Optimizely Opal tools make it easy for AI agents to call your APIs – in this post we’ll build a small ASP.NET host that exposes two of them: one fo...

Pär Wissmark | Dec 13, 2025 |