The Attack No One Sees Comes Through Your Site's Contact Form
The contact form looks harmless. It is the most open door you have, and almost nobody locks it.
Everyone protects the login. Nobody looks at the contact form. And yet it accepts input from anyone, with no authentication, no friction, often not even a send limit.
That is the asymmetry an attacker looks for. A text box that talks to your mail server, your database, or an internal webhook. You see a "message" field. They see a command line.
Why this target is so tempting
A contact form combines three rare properties in one spot. It accepts untrusted input. It runs logic on the server. And it almost never gets audited. The developer tested that the message reaches the inbox. They stopped there.
The trouble is that "the message reaches the inbox" hides an entire path. The user's text gets assembled inside an SMTP header, concatenated into a query, or shipped off to a third-party service. Each of those boundaries is a chance for injection.
Email header injection
The classic case is called email header injection. If you take the "subject" or "sender" field and drop it straight into the message header, an attacker writes a line break and adds their own headers. A Bcc to a thousand addresses, for example.
Suddenly your server is sending spam. Not in your name by coincidence, but literally through your infrastructure, with your IP and your domain. The outcome is predictable: the major providers flag your domain as a spam source, and your business email stops reaching anyone.
When text becomes code
Then there are the worse scenarios. If you store the message in a database without parameterizing the query, you open the door to SQL injection. If you render the message in an admin panel without escaping the HTML, the attacker plants a script that runs in your team's browser the moment they open the lead. This is stored XSS, and it is one of the most underrated vectors out there.
Notice the pattern. In none of these cases did the attacker "break into" anything. They used the form exactly as it was designed to be used. The vulnerability is not some exotic flaw. It is the absence of one simple rule: never trust what comes in.
What to do, in order of priority
You don't need a WAF or a security consultant to close 90% of this. You need discipline on four points.
- Validate on the server, never only in the browser. Front-end validation is a convenience for the user, not security. The attacker doesn't use your form, they POST straight to the endpoint.
- Escape on output, every time. When writing to a database, use parameterized queries. When rendering in a panel, escape the HTML. Treat every message as hostile until proven otherwise.
- Reject line breaks in header fields. Subject, name, and email have no reason to contain \r or \n. Filter them out before touching SMTP.
- Rate-limit submissions and add an invisible challenge. Rate limiting by IP plus a honeypot or hCaptcha stops automated bots without ruining the experience for real humans.
And the side almost everyone forgets
A contact form collects personal data. Name, email, often a phone number and the content of the message. That puts you inside the GDPR, whether you like it or not. You need a legal basis to process that data, and consent has to be informed.
In practice that means three concrete things. A clear privacy notice linked to the form. A defined legal basis, typically the legitimate interest of Article 6 or explicit consent. And a retention policy, because keeping leads forever is not a strategy, it is accumulated liability. If someone steals your lead database, the problem stops being technical and turns regulatory.
Form security is not an expensive firewall. It is refusing to trust the text a stranger typed.— Krivar Diário
The moral is boring, and that is exactly why it works. The attack no one sees comes through the door no one looks at. Treat your contact form with the same respect you give the login, and most of these problems never happen at all.