Skip to main content
EnglishEN EspañolES FrançaisFR DeutschDE ItalianoIT PortuguêsPT 中文ZH 日本語JA 한국어KO РусскийRU NederlandsNL
← Back to all articles

Contact Form Spam: Honeypots, Turnstile and reCAPTCHA Compared

Put a contact form on a website and the spam usually follows: link-stuffed messages, fake “SEO audits”, and gibberish that buries the one real enquiry you were waiting for. OWASP lists this as an automated threat in its own right, OAT-017 Spamming, which covers junk pushed through web forms, comments and similar inputs.

There are three common defences for a small business form: a honeypot field, Cloudflare Turnstile, and Google reCAPTCHA. They work in different ways and put different costs on real visitors. This guide explains what each one actually does, where each falls short, and a layered default that suits most small sites.

Key facts

  • Honeypot — A hidden field humans never fill in; free and invisible to visitors
  • 300 seconds — How long a Turnstile token stays valid, and it is meant to be used once
  • 0.0 to 1.0 — The reCAPTCHA v3 score range; Google suggests starting at a 0.5 threshold
  • Server-side — Every widget is useless unless your server verifies the token

Why contact forms attract spam

Most form spam is not a person typing. It is a script that finds forms, fills every field it sees and submits them in bulk. Some of it is selling something, some of it is trying to plant links, and some of it is testing whether your form can be abused to send email to other people. Because the scripts are cheap to run, even a tiny local business site gets hit.

The goal is not to stop every bot ever written. It is to stop the cheap, automated majority while costing real customers as little as possible. That trade-off is what separates the three approaches.

Honeypots: the free first layer

A honeypot is an extra form field that real visitors never see, such as a text input labelled “Leave this empty” and hidden with CSS. Simple bots fill in every field, so any submission with a value in the honeypot is discarded on the server. The W3C’s draft note on CAPTCHA alternatives describes honeypots as “easily implemented even in hand authored markup”, and they add nothing for the visitor to do.

Doing it properly

  • Hide the field with a CSS class, not type="hidden", because many bots skip hidden inputs.
  • Add tabindex="-1" and autocomplete="off" so keyboard users and browser autofill do not land in it, and give it a plain label in case a screen reader reaches it.
  • Check it on the server and drop the message quietly. Do not show an error that tells the bot what went wrong.
  • Many sites add a simple timing check too: a form submitted a second or two after the page loaded was almost certainly not typed by a person.

The limit: a honeypot only beats generic scripts. A bot written for your specific form, or one that drives a real browser, will leave the field empty. That is why it works best as one layer rather than the whole defence.

Cloudflare Turnstile

Turnstile is Cloudflare’s CAPTCHA alternative. You create a widget in the Cloudflare dashboard to get a public sitekey and a private secret key, add the widget script to your form, and verify the token it produces on your server. Cloudflare says Turnstile works on any website, whether or not the site is proxied through Cloudflare, and its plans page lists a Free plan with up to 20 widgets per account and unlimited challenges.

There are three widget modes. Managed, which Cloudflare recommends, decides per visitor whether to run a non-interactive check or show a checkbox, with no images or text to decipher. Non-interactive shows a spinner but never asks the visitor to do anything. Invisible runs with no visible widget, and Cloudflare requires you to reference its Turnstile Privacy Addendum in your privacy policy if you use it. Cloudflare’s documentation states that Turnstile is WCAG 2.2 AA compliant and that it does not access or store form entries.

Things to know

  • Tokens are valid for 300 seconds and are meant to be validated once, so a visitor who leaves the form open for a long time needs a fresh token.
  • The widget loads from challenges.cloudflare.com, so a Content Security Policy must allow that domain.

Google reCAPTCHA

reCAPTCHA comes in two main web forms. v2 Checkbox is the familiar “I’m not a robot” box: some people pass immediately, others are given an image challenge. v2 Invisible runs when the visitor clicks your submit button and only challenges the most suspicious traffic by default. v3 never interrupts the visitor; it returns a score from 0.0 (very likely a bot) to 1.0 (very likely a person), and your server decides what to do. Google suggests starting with a threshold of 0.5 and reviewing traffic in the admin console before tightening it.

With v3 you also get actions, a name for each place you run it, so you can check that the token came from the form you expected. Tokens expire after two minutes, so Google advises calling it when the visitor submits, not on page load. Google’s classic developer pages are now marked deprecated and point to its Google Cloud documentation, so check the current setup and terms there before starting a new integration.

The costs to real visitors

The W3C draft note on CAPTCHA accessibility reports that keyboard navigation with the v2 checkbox often triggers a traditional image challenge, and it describes v3’s cross-site signals as a significant privacy cost. A v3 score also leaves you to decide what happens to borderline visitors, so you need a fallback rather than silently rejecting real customers.

Whatever you choose, verify on the server

The most common mistake is adding a widget and never checking its token. Cloudflare is blunt about it: the client-side widget alone does not protect your form, because an attacker can send any string straight to your form handler. The same is true of reCAPTCHA.

  1. Your form posts the token along with the message.
  2. Your server sends the token and your secret key to the provider’s verify endpoint (for Turnstile, https://challenges.cloudflare.com/turnstile/v0/siteverify).
  3. Only if the response says success is true (and, for reCAPTCHA v3, the score and action are acceptable) does the server send the email or save the lead.

Keep the secret key on the server only, never in page source or JavaScript.

A sensible default for a small business site

For most service businesses getting a modest number of enquiries, a layered setup works well and keeps friction low:

  1. Start with a honeypot and a timing check. They are free, invisible and catch a large share of generic bots.
  2. If spam still gets through, add Turnstile in Managed mode and verify every token on the server. Most visitors never have to click anything.
  3. Filter what is left. Simple server-side rules, such as rejecting messages that are mostly links or that contain words your customers never use, catch the persistent leftovers. The W3C note lists spam filtering among the alternatives that add no burden for users.
  4. Rate-limit the form so one source cannot submit hundreds of times an hour.
  5. Test it yourself with a keyboard and on a phone after every change, and send a real test message to make sure leads still arrive.

reCAPTCHA is still a reasonable choice if you already use Google services and are comfortable with its privacy terms. What matters most is the layering and the server-side check, not the brand of widget.

Sources

Related reading

Frequently asked questions

Is a honeypot enough to stop contact form spam?

Often it stops a large share of generic bots, because they fill in every field. It will not stop a bot written for your specific form or one that drives a real browser, so add Turnstile or reCAPTCHA if spam keeps getting through.

Is Cloudflare Turnstile free, and do I need Cloudflare hosting?

Cloudflare's plans page lists a Free plan with up to 20 widgets per account and unlimited challenges, and Cloudflare says Turnstile works on any website whether or not it is proxied through Cloudflare.

Why am I still getting spam after adding a CAPTCHA?

The most common reason is that the token is never verified on the server, so bots post straight to the form handler. Check that your server calls the provider's verify endpoint with your secret key and rejects anything that fails.

Want a contact form that delivers leads, not spam?

BuiltToWinWeb builds custom sites with forms that are fast, accessible and verified on the server. Get a free quote.

Get a free quote