Protect a contact form in layers and measure the effect on real users. Start with server-side validation, add low-friction bot signals, rate-limit abusive patterns, and introduce an accessible challenge only when necessary. Every change should be tested with keyboard navigation, assistive technology, slow connections, and common privacy tools.
Establish a baseline
Record the number of legitimate submissions, obvious spam messages, repeated sources, delivery failures, and user complaints during a representative period. Do not store more personal data than the business needs. Keep operational security logs separate from message content where practical, and set a retention period for both.
Verify the basic form before adding defenses. Each field needs a visible label, useful instructions, sensible length limits, and server-side type and size validation. Display a clear success message only after the server accepts the message. Preserve entered values when an error is correctable, and never rely only on color to identify the problem.
The W3C form notification tutorial recommends concise success and error feedback, clear correction instructions, and programmatic associations between fields and their error messages. This protects legitimate users from becoming indistinguishable from failed bot traffic.
Add low-friction controls first
Use a server-generated request token, a short-lived submission window, and a hidden field that ordinary users never fill when those controls fit the site's architecture. Reject impossible payloads and repeated bursts on the server. Rate limits should be narrow enough to slow automation but should allow shared networks, retries, and people who need more time. Log the reason category rather than the full message when diagnosing a block.
Do not depend on client-side JavaScript validation alone. Automated clients can submit directly to the endpoint, so the server must enforce required fields, size limits, allowed formats, origin expectations, and any challenge result. Return generic public errors while keeping actionable internal diagnostics.
Add a challenge carefully
If spam remains high, choose a challenge with documented accessibility behavior and provide a recovery path. W3C guidance on CAPTCHA explains that sensory CAPTCHA can exclude users and requires alternatives for different sensory needs when used. Avoid puzzles that depend on sight, hearing, cultural knowledge, or rapid interaction.
When using a token-based service, validate the token on the server and bind it to the intended form. Cloudflare's Turnstile documentation describes a client widget that produces a token and a server-side Siteverify call that validates it. A successful visual interaction without server verification is not sufficient. Keep the secret key out of the page source and logs.
Test legitimate-user paths
Submit the form with a keyboard only, a screen reader, a mobile device, a slow connection, JavaScript delayed, and a privacy or content blocker. Test expired tokens, duplicate clicks, a server timeout, and a rejected attachment. Confirm that users receive a clear explanation and can retry without retyping the whole message. Provide an alternate contact route when the form cannot be completed.
Review false-positive evidence after launch. Compare spam reduction with successful submissions, abandonment, verification failures, and support contacts. Relax or replace a control that blocks legitimate users even if it also blocks spam. Recheck the form whenever its provider, script policy, challenge settings, mail delivery, or page template changes.
Document the chosen layers, server checks, rate-limit boundary, challenge configuration, accessibility results, error behavior, and rollback step. The goal is not a perfect spam score. It is a form that remains dependable for real customers while making automated abuse expensive and visible.
Sources
- User Notification โ W3C Web Accessibility Initiative
- Understanding Success Criterion 1.1.1: Non-text Content โ W3C Web Accessibility Initiative
- Get started with Cloudflare Turnstile โ Cloudflare Developers