There has always been a need to create anti-spam forms without using CAPTCHA or other forms of the “I am not a Robot” type user experience nightmare.

Anti-Spam Forms Without CAPTCHA

We all feel the pain…having a contact form on our web sites, only to have 90% of it’s use be from autobot spammers. Then we put on CAPTCHA, reCAPTCHA or similar annoying things to try to weed out autobots. With a couple little tricks, you can create anti-spam forms with such user experience impacts. I have also successfully added this to my Formmailer Form Processor for personal use, and will add it as an option to the rebuild.

Of course these tools force the visitor through more screens of “select all [whatever]” image selections. Or worse, skew a picture of 5 or 6 characters so much even a human with perfect vision has a hard time reading them.

I may have a solution. Of course after publishing this it may not be a solution for long, but I have to share.

After testing thousands upon thousands of form submissions over the course of a year (yes this has been a pandemic boredom project), I have come up with an idea. Over the thousands of submissions I’ve recieved, it’s generated only one false positive. Even that one, after analysis, I question if that was a real email.

So let’s have a look at my method, see if it might work for you. If you have suggestions on how to make it better, or share your own methods that you have tried to accomplish the same task, I’d love to hear about it. Let’s create some anti-spam forms!

The Anti-Spam Forms Method

There are two different tools in use here:

  • The good ol’ tried and true “honeypot” method. This is a very old, but still effective, idea of putting a checkbox on the form, and then using CSS to hide it so a real visitor would not see it.
  • Creating a timestamp just as the form loads on the page, and a timestamp of the time the form gets submitted or hits the processing script.

The Honeypot

What I did was create a <div> with a checkbox inside of it, with a name and id of “accept”. Added some text along with it along the lines of “I accept the terms and conditions…” for the appearance of legitimacy. Then use a display:none; CSS definition to hide the entire <div> from the browser.

Upon processing, if that checkbox is checked, it’s clearly a bot filling out the form that is just filling out fields it sees, so, it’s spam.

However, while uncommon, that method has been caught on to by a few clever spammers. So every now and then I’d see one get past it, so we need one other method to catch those.

The Time Check

So, in order to catch those, I have done this; which varies by the platform your website uses. As the form page loads, grab the current timestamp and put it into a variable. Then, after the form submits, take the timestamp there and put it in a different variable.

Before processing the form and sending the email, compare the timestamps, if they are less then 5 seconds or so, you can be pretty confident it was submitted by a bot. I have, for my forms, timed myself filling it out as fast as I can with as short of a comment/message/body as possible. Then use a time just a couple seconds shorter than that as the time to compare against.

Then, before sending the email, check the checkbox value, check the difference between timestamps, and if it’s clean, send it on, if not, trash it.

Development Tips and Thoughts

This theory of anti-spam forms I have found this very helpful to me. I use a free email API service with limits on the usage of it. I now do the checks before it gets sent to the API, so only clean submissions ever see the API. Doing so have dropped my usage number a great deal.

There is no reason this same theory can’t be used with any other platform. You would just need to verify the syntax of getting timestamps and doing the math. Myself, being primarily a PHP guy, I default to that.

How I Tested Anti-Spam Forms

Anti-Spam Project

I built a database and browser based reporting tool. I took three of my web sites and converted the anti-spam forms to use the above methods to filter the content. Then every form submission I added to the database with time, date, IP, geolocation, form field values and such information.

What I have found is that my higher traffic websites get about 20-30 form submissions daily of which one or two are actually legitimate. For quite a while every day I would log in and look at the results and check for false positives and look at the legit email. AFter analysis for many weeks I have found the results almost 100% accurate.

I hope, at some point, to have time to make WordPress and Drupal modules using this method. I would love to see a world without CAPTCHA as much as a world without spam. Feel free to use this at will, and if you feel so inclined, let me know the results.