Development

Contact form without reCAPTCHA — catching bots without Google

Most spam on contact forms does not come from humans — it comes from bots. Bots behave differently from humans, and that difference is enough to build protection on without Google's help.

Why replace reCAPTCHA

reCAPTCHA v3 works — that cannot be denied. Google's model is trained on billions of signals and the score-based approach is intelligent. But it comes at a price that is not paid in money.

Privacy. reCAPTCHA loads a script from Google that tracks the user throughout the browser session. Google learns which site the user visited and when. This is not hypothetical — it is their business model.

GDPR. Because of the third-party tracking, using reCAPTCHA formally requires user consent. In practice many sites ignore this requirement, but that does not make it compliant.

Load time. The reCAPTCHA v3 script is ~30 KB, loads from Google, and adds one external request to the page load latency.

The alternative does not have to be complex. Bots behave differently from humans. Catching that difference requires only a few simple checks.

How the protection works

Every form submission passes through several layers in sequence. The earlier a bot is caught, the better — later checks are more expensive.

Layer 1: Honeypot

A hidden field is added to the form — one that a human never sees or fills in. A bot fills in every field it can find, including this one. If the hidden field is filled, the sender is a bot.

One important detail: the bot does not get an error. The server responds with success, as if everything went fine. If it got an error response, it would learn to skip that field next time. A deceptive success response keeps it repeating the same pattern.

Layer 2: Timing check

A human opens a form, reads it, thinks, types — this takes time. A bot submits within a fraction of a second of loading the page.

When the page loads, the time is recorded. On the server, we check whether at least three seconds passed before submission. Under three seconds — bot. Over two hours — the form is too old, likely a replay attack. Both get silent success, not an error.

Layer 3: IP rate limiting

Even if a bot passes the previous layers, it can only send five messages from a single IP address per hour. The sixth attempt gets a clear error message. This is the only layer that communicates honestly — a legitimate user should know if they have hit a limit.

Layer 4: Email domain checks

Two checks in one layer. First — about 130 known disposable address services (Mailinator, Guerrilla Mail, YopMail, etc.) are on a blocklist. Second — if a domain is not on the known list, a DNS lookup checks whether it has a mail server at all. A domain without a mail server is effectively an unusable address.

Layer 5: Stop Forum Spam

Stop Forum Spam is a free public database of known spammer IP addresses and email addresses. Every submission is checked against their API. Only high-confidence matches are blocked — a lower threshold would mean too many false positives.

If the API does not respond (network error, timeout), the submission is allowed through. When in doubt, reliability comes first.

Layer 6: Content filter

Many bots send messages with characteristic content — casino, viagra, SEO services, backlinks, crypto. A score-based filter adds points for suspicious keywords. One keyword does not block; a combination does. This reduces false positives compared to hard-coded blocking.

Alternatives

A local solution is not the only option. Here are the main alternatives and their trade-offs.

Cloudflare Turnstile is free and privacy-friendly — it does not track the user and does not require GDPR consent. It works similarly to reCAPTCHA v3 but through Cloudflare's servers. A good choice if your site is already behind Cloudflare. Downside: third-party dependency remains, just Google replaced by Cloudflare.

hCaptcha is another popular reCAPTCHA alternative — more privacy-conscious, paid for higher volumes. It occasionally asks users to solve image recognition challenges, which some find annoying.

Akismet is the spam filter from Automattic, the company behind WordPress. Works well for WordPress forms but is not designed for custom PHP solutions. Free only for non-commercial sites.

Math CAPTCHAs ("What is 3+4?") work against simple bots but require user interaction and are easily automated. Worst option from a usability perspective.

Cloudflare WAF is the right tool when volume is high — thousands of bot attempts per day. Requires a paid Cloudflare plan, but provides broad protection against other attack types as well.

The local layered solution works best for small to medium traffic sites where you want full control and GDPR cleanliness without external dependencies.

What this solution does not do

Distributed attacks. If a thousand different IP addresses each send one message, the rate limiter only stops repeat offenders. At that volume, Cloudflare WAF or similar is a better fit.

Highly sophisticated bots. This works well against typical bot traffic. If someone targets your form specifically and adapts their bot accordingly, some will get through. Against that kind of adversary, automated filtering is not the right tool — human review is more useful.

The result

A contact form with no reCAPTCHA, zero scripts loaded from Google, full GDPR control.

Protection layers in order: origin check → honeypot → timing → email validation → IP rate limiting → Stop Forum Spam → content filter.

Each layer is independent. If one lets something through, the next catches it. Get in touch if you want the same approach for your own form.

Kaido Toomingas Kaido Toomingas WebPro Company OÜ

Need Drupal help?

If the article describes your situation, you do not have to read everything first. A real person will help you choose the next step.