AUTOMATION
Bots that fill and submit
Automated scripts look for public forms, fill fields, insert links and consume the outbound email service.
Guides
A form that says “message sent” does not prove that the enquiry arrived. It needs layered protection, server-side validation, accessible feedback and an email flow tested all the way to a real mailbox.
The short answer
A reliable contact form asks only for necessary data, validates every field on the server, limits automation without relying on one control, uses a sender on the website domain and the user’s address as Reply-To, shows success only after the main notification is accepted by the transport, then verifies SPF, DKIM, DMARC and receipt with a real message.
The journey does not end when someone presses the button. Every link must work, from the completed field to the mailbox that receives it.
A form connects browser, server code, email service, DNS and the destination mailbox. One weak configuration can produce spam, silent errors or false confirmations.
AUTOMATION
Automated scripts look for public forms, fill fields, insert links and consume the outbound email service.
HEADERS
If email, subject or other data enter headers unchecked, CR/LF characters can attempt to add recipients or unwanted fields.
VOLUME
Even formally valid data becomes abuse when the same feature is called hundreds of times.
DELIVERY
A local transport can take the message and later encounter rejection, spam filtering or an authentication problem.
USABILITY
A coloured border is not enough: keyboard, screen-reader and magnification users must identify the error and reach its field.
DATA
Excess fields, full-content logs and trackers loaded on the form increase friction, responsibility and the surface that needs protection.
Before adding technical controls, decide what information is genuinely needed to begin a conversation.
MINIMISATION
W3C notes that people prefer short, simple forms. Asking for irrelevant or premature data makes abandonment more likely.
Name, contact details, context and message may be enough for many websites. Company, telephone, budget or URL should become mandatory only when the process truly requires them.
A field is not necessary merely because it might be useful later. It must serve the request the person is making now.
Telephone, existing website or company can help, but should not block an initial enquiry when they are not essential.
Labels, options and introductory copy should explain who receives the data and what response to expect.
Consent and the privacy notice link must be clear, consistent with the actual processing and usable from a keyboard.
HTML attributes and JavaScript improve the experience, but a request can be built without using the page. The server must therefore check everything again.
| Field | In the browser | On the server | Why |
|---|---|---|---|
| Email type and maximum length | Format, length and control characters | The value enters the reply flow and must not alter headers | |
| Telephone | Suggested format and maxlength | Characters, length and plausible value | A free input must not accept arbitrary payloads |
| URL | URL type and instructions | HTTP(S) only, length and syntax | An unchecked address can become ambiguous or dangerous downstream data |
| Topic | Choice among visible options | Exact match against an allowlist | The client can be changed to submit options that were never offered |
| Message | Minimum, maximum and instructions | Length, normalisation and safe output encoding | Free text is legitimate, but needs boundaries and must be treated as data |
Client for usability, server for trust
OWASP recommends server-side syntactic and semantic checks, minimum and maximum lengths and allowlists for enumerated values. Validation does not replace correct encoding when data are displayed or inserted into email.
A robust defence combines low-friction signals. The goal is not to prove humanity at any cost, but to make automation less reliable and limit its impact.
A field hidden from people but found by automated fillers identifies many requests built without understanding the page.
The server checks that the form was neither submitted impossibly quickly nor reused beyond its validity.
A control generated by the website can add light friction without loading reCAPTCHA, profiling or third-party resources.
HMAC and expiry times identify altered or recycled parameters without creating visitor cookies or sessions.
Attempts remain limited across separate requests, so reopening the page does not reset the control.
An ordinary contact form can avoid third-party widgets. An external challenge remains a proportionate choice only when risk and abuse require it.
A counter kept only in the browser session is easy to reset. The application limit needs minimal, atomic and non-public state.
Elements used to distinguish sources are transformed with HMAC; the file stores neither IP nor email in plain text.
Timestamps and counters survive subsequent requests and are updated without races between simultaneous submissions.
The limit should stop abnormal bursts without preventing a shared network or real person from correcting an error.
When the threshold is exceeded, the system does not reveal details that help tune the bot and asks the person to try later.
PROXIES
The conservative default is REMOTE_ADDR. A client-supplied header can be forged and must not automatically become the rate-limit key.
X-Forwarded-For is interpreted only when the request arrives from a genuinely known proxy declared with verified IP addresses or networks.
From and Reply-To solve different problems. Confusing them weakens authentication, reliability and header security.
PRACTICAL RULE
The notification is sent from a real address belonging to the website domain. The email entered in the form is used for replies, not to pretend that the message was sent by that person’s domain.
Subjects, addresses and names used in headers are checked and stripped of CR/LF characters. Every message also receives a coherent, unique Message-ID.
Identifies the technical sender authorised by the domain and must match the service that sends the message.
In the internal notification it contains the visitor’s address, so Reply opens the correct conversation.
Distinguishes the message, uses the website domain and helps correlation, diagnostics and technical flow tracking.
External values must not be able to introduce new lines, recipients, blind copies or instructions into the message.
The sending order determines what the confirmation shown to the person really means.
Success only after the main notification
If the transport rejects the internal notification, the website should show a useful error and not generate the signed success state. If only the autoreply fails, the already acquired enquiry remains valid.
Code can construct the message correctly, but the domain and infrastructure must prove to recipients who is authorised to send it.
SPF
The DNS record lists systems authorised for the domain used in the SMTP path. A message from an unexpected source can fail the check.
DKIM
The server signs parts of the message; the recipient retrieves the public key from DNS and verifies the signature and domain.
DMARC
Connects the domain shown to the user with an authenticated SPF or DKIM identity and publishes a policy for messages that fail.
TLS
Protects the connection between compatible servers. It does not replace SPF, DKIM or DMARC and does not by itself prove legitimacy.
Deliverability is not proven by querying DNS or looking at the confirmation on the website. A controlled procedure must reach an external mailbox and separate every link in the chain.
TESTING PROTOCOL
Send a controlled enquiry to an external address, verify that the main notification precedes the autoreply, and confirm that the website does not show false success when transport rejects the message.
Inspect the original source for Authentication-Results, Return-Path, From, Reply-To, Message-ID, Received hops and TLS information when the recipient exposes it.
Signed success state produced only after acceptance of the main notification.
A simulated rejection must not produce success; an accepted message must continue towards the external recipient.
Recipient headers must make it possible to inspect SPF, DKIM, DMARC alignment and the policy published by the domain.
Check notification and autoreply in inbox and spam; test Reply-To and the original source rather than merely reading the configuration.
A successful test is not an eternal guarantee
The test describes one flow, one configuration and one point in time. DNS, providers, reputation, content and filters change: repeat it after transport changes and monitor it over time.
Contact-form accessibility is more than labels. It includes instructions, associations, summary, focus and the ability to correct an error without starting again.
Every control has an understandable name technically connected to the field, including for screen readers and voice input.
Required fields and formats are declared before an error, without relying on colour or an asterisk alone.
After submission, an announceable block lists what is wrong and links directly to the fields that need correction.
aria-invalid and aria-describedby associate the state and explanation with the affected control.
Focus reaches the summary or first error without trapping the keyboard or hiding the context.
Allowed values remain available after an error within the configured limits; passwords, tokens and anti-spam fields are not repopulated.
For duties, WCAG and the difference between a preferences panel and full conformance, read the website accessibility guide.
Diagnostics help when they distinguish abuse, rejection and success. They become a risk when logs copy names, emails, messages and addresses without a genuine need.
Technical logs can keep date, language and predefined event codes while avoiding free text and enquiry content.
Anti-abuse state uses non-reversible references instead of storing IP addresses and emails in plain text.
Validation failed, limit exceeded, transport rejected and notification accepted should be distinguishable without exposing visitor data.
When measurement is active, the contact event is emitted only from the signed success state and contains no fields, query or personal properties.
The checklist separates what can be seen on the page, what must be tested on the server and what only an external mailbox can confirm.
| Area | What to verify | Concrete proof |
|---|---|---|
| Fields | Necessary data only, consistent required and maxlength | Valid submission and attempts beyond each limit |
| Validation | Format, length, allowlists and safe encoding | POST requests built outside the browser and altered values |
| Anti-spam | Honeypot, timing, signatures and light verification | Trap field, very fast submission and tampered tokens |
| Rate limit | Persistence, atomicity and no plain-text data | Burst of separate requests and inspection of state |
| Proxy | REMOTE_ADDR by default, declared trusted proxies | Forged X-Forwarded-For and request through a known proxy |
| Email headers | Domain From, user Reply-To, Message-ID and CR/LF | Original source and header-injection attempts |
| Order | Main notification, signed success, then autoreply | Rejected main transport and simulated autoreply failure |
| DNS and authentication | SPF, DKIM, DMARC and alignment | Authentication-Results from an external mailbox |
| Delivery | Notification and autoreply received, inbox and spam checked | Real sending to relevant domains and mailboxes |
| Accessibility | Labels, instructions, errors, focus, keyboard and value preservation | Deliberate errors using keyboard and assistive technology |
An automated scan cannot certify delivery by itself. Testing ends only when an external mailbox shows the message and its Authentication-Results.
I do not add a form at the end of a project as a decorative element. I treat it as a public function that collects data, triggers email and can become a target for automation.
TECHNICAL STANDARD
The shared foundation includes accessible structure, server-side controls, layered protection, persistent rate limits, coherent headers and a success state tied to the main notification.
Each website is then configured on its own domain and tested with real recipients. No solution guarantees zero spam or permanent delivery: it reduces risk and makes every link in the system verifiable.
No cookies, sessions or reCAPTCHA are needed for the ordinary protection of the form.
Honeypot, timing signatures, signed checks, limits and rate limiting cover different abuses.
Summary, field links, focus, ARIA and preserved values help people correct errors without starting again.
Domain From, correct Reply-To, Message-ID and notification-autoreply order are part of the module.
Testing covers transport, receipt and original headers, not only the appearance of a website confirmation.
Changes to hosting, DNS, mailboxes or transport require the chain to be tested again.
Also explore website security, the cookieless approach and why a website may fail to generate enquiries.
The guide’s recommendations come from primary technical documentation and a testing protocol that can be applied to the real system.
Syntactic and semantic validation, allowlists, limits and the need for server-side checks.
Layered defences, honeypots, rate limits and the weakness of single anti-automation controls.
Labels, instructions, validation, notifications and the recommendation to ask only for necessary data.
Error summaries, understandable messages, field links, ARIA and focus management.
Header security and the explicit distinction between acceptance for delivery and arrival at the destination.
Gmail requirements and guidance for SPF, DKIM, DMARC, alignment, TLS and message format.
Current standard covering authenticated identities, alignment, policy, p=none monitoring and aggregate reports.
Cryptographic signatures, signing domains and verification through a public key published in DNS.
Sources checked on 27 August 2026. DNS configurations, providers, interfaces and recipient requirements can change and must be rechecked on the real system.
Direct answers about spam, CAPTCHA, rate limits, email, SPF, DKIM, DMARC, autoreplies, privacy and delivery.
No. It blocks many simple bots, but those that interpret the page or send targeted requests can avoid it. Combine it with timing signatures, validation, rate limits and monitoring.
No. Many ordinary forms can use local protections without reCAPTCHA or external tracking. An additional service may become proportionate when volume, risk or distributed abuse exceeds application defences.
No. It improves usability but can be bypassed by constructing the HTTP request directly. Every field must be checked again on the server.
The website is not authorised to send on behalf of the visitor’s domain. From should belong to the website domain; the submitted address belongs in Reply-To on the internal notification.
It means the transport accepted the message locally, not that the final mailbox received it. Delivery is verified with a real message and the recipient’s original headers.
SPF confirms that the source is authorised, DKIM verifies the domain signature and DMARC checks that at least one authenticated identity aligns with the visible From domain.
No. Messages can pass DMARC, while p=none indicates a monitoring policy that does not ask the recipient to quarantine or reject non-compliant mail.
No. Automated confirmation and human reading are different events. The autoreply should follow the main notification and accurately say that the request was acquired.
Yes, if thresholds and identification are poorly designed. It must be proportionate, account for shared networks, distrust unverified proxies and allow normal error correction.
After launch and changes to code, hosting, DNS, mailboxes or transport, and periodically within maintenance. Test notification, autoreply, Reply-To, inbox/spam and Authentication-Results.
Next step
Security, accessibility, privacy, performance and tested forms are part of the technical standards of the bespoke websites I build.