Securing Website Forms Without Losing Enquiries

How to protect contact and enquiry forms from spam without losing real enquiries: honeypots and timing checks, rate limiting, invisible challenges, reliable email delivery, stored submissions and consent.

Contact and enquiry forms are where search and AI visibility turn into business, so they must stop spam without stopping real people. The best protection is layered and mostly invisible: a honeypot field, a minimum time before submission, rate limiting and server-side validation, with an invisible challenge such as Cloudflare Turnstile or reCAPTCHA v3 only if spam continues. Add reliable email delivery, secure storage of submissions and clear consent, and the form stays both safe and easy to use.

Why heavy CAPTCHAs cost enquiries

Puzzles and image challenges frustrate people, especially on mobile and for users with disabilities, and some give up. Invisible checks stop most automated spam without asking anything of real visitors.

Layer 1: honeypot and timing

A honeypot is a field hidden from people with CSS, which bots tend to fill in. A timing check rejects forms submitted faster than a person could type. This Laravel middleware applies both:

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class SpamGuard
{
    public function handle(Request $request, Closure $next)
    {
        if ($request->filled('website_url')) {            // honeypot, hidden with CSS
            return back()->with('status', 'Thank you.');  // do not reveal the check
        }
        $renderedAt = (int) decrypt($request->input('form_ts', encrypt(0)));
        if (time() - $renderedAt < 3) {                   // submitted in under 3 seconds
            return back()->withErrors(['form' => 'Please try again.']);
        }
        return $next($request);
    }
}
{{-- in the form --}}
<input type="hidden" name="form_ts" value="{{ encrypt(time()) }}">
<div class="hp" aria-hidden="true">
  <label>Leave this empty <input name="website_url" tabindex="-1" autocomplete="off"></label>
</div>
/* CSS: .hp { position: absolute; left: -9999px; } */

WordPress form plugins such as Contact Form 7 offer honeypot add-ons with the same idea.

Layer 2: rate limiting and validation

  • Limit submissions per IP address, for example with Laravel’s throttle middleware.
  • Validate every field on the server: required fields, email format, maximum lengths.
  • Reject links in fields where they make no sense, such as a name field.
  • Keep CSRF protection enabled.

Layer 3: invisible challenges, only if needed

If spam still gets through, add an invisible or low-friction challenge: Cloudflare Turnstile or reCAPTCHA v3, which score requests in the background. Load the script only on pages with forms, to protect performance.

Make sure enquiries arrive

  • Send form emails through authenticated SMTP from your own domain, not the server’s default mail function.
  • Publish SPF, DKIM and DMARC records for the sending domain.
  • Store a copy of every submission in the database, so nothing is lost if email fails.
  • Test the form after every change, and check that messages land in the inbox, not spam.

This site’s contact form follows the same pattern: every submission is saved in the database, the domain publishes SPF, DKIM and DMARC records, and the recipient address is never shown on the page.

  • Collect only the fields you need.
  • Explain how the information will be used, with a link to the privacy policy and a consent checkbox where required.
  • Protect stored submissions and delete them when no longer needed, under the Digital Personal Data Protection Act, 2023.
  • Restrict file uploads to safe types and sizes, and scan them if possible.

Frequently asked questions

Do CAPTCHAs affect SEO?

Not directly, but heavy scripts on every page slow the site, and friction lowers conversions. Load challenges only where needed.

Should we show our email address instead of a form?

Showing an address invites spam harvesting. A well-protected form with a stored copy of submissions is more reliable.

How short should a contact form be?

As short as the enquiry allows: name, email or phone, and a message are often enough, with optional fields for details.

Sources

  1. Laravel documentation, middleware, rate limiting and encryption
  2. Cloudflare Turnstile and Google reCAPTCHA documentation
  3. Digital Personal Data Protection Act, 2023