Securing Forms Without Captcha

Captchas are a terrible user experience.

I've seen more captchas like this than I can count.

I’ve seen more captchas like this than I can count.

They put the onus of spam protection on the visitor filling out the form and, personally, show me how lazy you are as a site administrator.  There are a hundred different ways you can protect your site from spam on the server side – why would you forego these options and force your visitors to jump through additional hoops?

Furthermore, captchas can negatively impact the overall user experience on your site for some. They can actually hurt your conversion rate for others.

Instead of using a captcha, let’s look at two passive things you can add to a form to reduce spam.

Submission Timer

In general, humans are slow.  This is one of the reasons we invented computers and started scripting bots to begin with – non-humans are quicker and more efficient at completing certain tasks than we’ll ever be.

And that can also be their disadvantage.

Add a hidden field to your form that contains the current server time (based on when the form was generated).  Then, upon submission, check the form’s timestamp against the current server time.  If the form was submitted too quickly (say, less than 3 seconds) then a human probably didn’t fill it out.

    <input type="hidden" value="<?php echo time(); ?>" />
    <input type="text" name="email" />
    <input type="submit" value="Submit" />

Twitter, for example, uses a similar timer to secure submissions to their API.  Most API requests require a server timestamp.  Twitter requires the request timestamp be within five minutes of their server time in order to be marked as “valid.”

This approach won’t work if you use full-page caching on your system, though.  So be sure to disable the cache for your form pages.


A honeypot is a trap used to detect bots. It’s a form field that, usually, is invisible to real visitors but seen – and completed – by scripts, bots, and other programs trying to attack your form.

A bot is typically smart enough to fill fields labeled “email” with a valid email address so they can skip past validation routines. Like their speediness, this trait can be used to identify and reject submissions from bots.

For our purposes, we rename our regular email field and add a new email field that will be hidden later by CSS.

<style type="text/css">
    .email-block { display: none; }
    <p class="name-block">
        <label for="name">Name:</label>
        <input type="text" name="name" />
    <p class="email-block">
        <label for="email">Leave this blank if you're human</label>
        <input type="text" name="email" />
    <p class="alternate-block">
        <label for="alternate">Email:</label>
        <input type="text" name="alternate" />
    <input type="submit" value="Submit" />

When viewed in a browser, the entire email block will be hidden from the user – they can’t fill in the “email” field by mistake. Even if they’re using a text-based browser or a screen reader that ignores the display: none; declaration, we clearly label the field in such a way as it should be ignored.

Bots, however, will fill in the field. When processing the request on the server side, we can reject it wholesale if “email” is non-empty.

Further Protection

These are just two passive routes you can take to secure contact, purchase, comment, or other forms on your website. They’re almost entirely transparent to your visitors and thus won’t carry the same frustration and distasteful UX of a captcha. At the same time, they’re nearly as effective at blocking spam submissions.

For spam that does continue to make it through, you can turn to active prevention techniques like an IP block list or a service like Akismet.

An IP block list is a hand-curated list of addresses known to generate spam – requests coming from these IPs can and should be ignored. You can curate the list yourself, or turn to one of any of the publicly curated lists available online.

Akismet will scan the content, referer, and IP address of a comment or form submission and compare it against a database of known spam. Potential spam submissions are flagged as such and can either be ignored or cached (to allow manual double-checking for false-positives). The service is free for personal use, or there are reasonably priced plans for commercial sites.

Whatever route you take, there are always both passive and active alternatives to captchas. Avoiding captchas will improve your conversion rate and make the experience of using your site that much more pleasant for any visitor who comes along.

About Eric

Eric Mann is a writer, web developer, and outdoorsman living in the Pacific Northwest. If he's not working with new technologies in web development, you can probably find him out running, climbing, or hiking with his dog.


  1. Are there any plugins for WP that do this already, especially for bbPress and BuddyPress register pages?

  2. I just wanna let you try this captcha. If you still disagree, just leave it. Thx

    • It’s still a captcha. Captchas still require additional user input to submit a form – this input isn’t part of the form and is instead meant to save you as the site administrator time (otherwise spent clearing out spam entries). The point of the website isn’t to make things easier for you, it’s to make things easier for your customers. Captchas are an unnecessary barrier between your customers and your call to action.

  3. I agree, I dislike captcha, and especially difficult ones like ReCaptcha. I can’t get them right half the time. However, these are weak solutions offered in your post.

    Submission Timer – can’t the spammers just put a delay on their script? Sure maybe most won’t but this is a pretty obvious weakness to this technique. If everyone had a required delay, then I’m pretty sure the spammers would react. It only works now because most sites don’t and most spammers don’t bother to include the ones that do.

    Honeypot – I’ve used honeypots myself and it works sometimes. Some scripts must actually check if they are made hidden with whatever technique. It’s easy for a script to check for “display: none” for example.

    I’ve been searching for something different from Akismet because I don’t get many comments and I don’t feel like wading through the spam comments anymore to check for false positives. That shouldn’t be the reason I’m forced to check my hobby site as often as I do, which is maybe every couple days.

    • If there is a path for legitimate comments to make it through to your site, a spammer will find a way to automate that and inject spam. While these methods might be “weak” when faced against a determined spammer, they are sufficient to block the majority of automated spam.

      For a personal hobby site (i.e. a non-business site) you can likely use Akismet for free. It’s number of false positives is low enough that I usually ignore even checking (in the 5 years I’ve used Akismet, I’ve had a total of 3 false positive comments).

      • Thanks for your reply. Well, I’ll say a little embarrassingly that I only have one comment on my site, and it was in the spam when it came in with Akismet so that’s 100% for me :) I guess if I had more to go by, then I would feel comfortable just emptying spam without checking and much less often.

        I agree those methods would block the majority of automated spam. But if in the future, every site had a delay and honeypots, then it probably would get a lot more spam. Right now it’s kind of like the saying that you don’t have to outrun the bear, you just have to outrun the guy next to you. I’ll look into using them but I don’t want to do something custom myself.

        And what if I ever put ads on my site? It’s not totally clear right away since they use words like “non-business personal sites” for the Personal option. If I had an ad up there, I don’t know if I’d call that a business site yet. I see this on Akismet’s site: “If your site is for a business or if it promotes a product or service, you should pick from one of our paid account options.” This makes me think one ad would do it though and I’d have to try something else. I wonder what happened when all the WordPress users who used Akismet for their personal sites and have ads saw this change. It seems like they’re not being really strict, just asking more effectively for money.

  4. Without digging into a test form, I’m pretty sure Formidable Pro can handle the Honeypot strategy. The others… not so much. It might be nice if Sector 11 could integrate the other two methods.

    Thanks for the post!

  5. Maybe I don’t understand (being a nube in html) but the examples don’t seem to be complete, and I can’t get anything to work on my test site. Spam is getting bad.

    • The examples are not complete. They’re merely how to render HTML that has the specified safeguards in place. Implementing the server-side checks to accept or reject content based on these safeguards is a second step that’s explained above, but I don’t provide the code for it.

Leave a Reply