Back

Bots find your inquiry form before customers do

October 2, 2026 · Musings

Put an inquiry form on your company website, and the first ones knocking are rarely customers — they're bots that crawl the web looking for forms to fill. Thales' annual Imperva Bad Bot Report put it at 51%: in 2024, automated bot traffic exceeded human traffic for the first time in a decade, with malicious bots alone at 37%1. To an unprotected form, more of your "visitors" are bots than people.

An unprotected form isn't a "few extra junk messages" problem — it has real costs. And installing defenses isn't the end either: whether a defense is alive must be proven by real attack. This post covers what an unprotected form costs, what the mainstream options are, and the trade we make.

TL;DR:

  • In 2024, automated bots carried 51% of all internet traffic — past humans for the first time in a decade. An unprotected inquiry form gets more bot visitors than people
  • The cost is three bills: spam buries real inquiries, unbounded writes eat your storage — and if the form mails outward (auto-replies especially), your domain's reputation goes too
  • Mainstream tools fall into four families — filtering services, CAPTCHAs, honeypots, rate limiting — usually combined; there is no best one, only a fit
  • Defenses fail silently — installed is not the same as alive, and only real attacks prove which one you have

What an unprotected form costs: three bills

Form spam means malicious or junk content submitted in bulk through a web form by machines. OWASP gives it its own entry in its taxonomy of automated threats to web applications, listed alongside credential stuffing and scraping2.

When the bills arrive, there are three:

The first is collected in attention. Spam and genuine inquiries pile into the same inbox; sort by newest, and junk sits on top forever. Deleting a hundred spams takes a few minutes; missing one real inquiry can cost you a customer.

The second is collected in storage. Every submission leaves a trace: logs, data records, mail copies. Unbounded writes fill your own storage. "A form filling up your storage" sounds dramatic, but as long as submissions cost nothing, filling it is only a matter of time.

The third is collected in reputation — whether it arrives depends on how the form is wired. If submissions only land in server-side storage, this one never applies; if the notification mail goes from your domain to itself, external reputation isn't touched either — at worst your own inbox floods, which is the first bill again. The dangerous wiring is anything that mails outward. The classic case is the auto-reply: the form sends a confirmation to whatever address the submitter typed. An attacker fills in other people's addresses and pumps junk through — now your domain is spamming on their behalf, and receiving providers and blocklists charge every message to your name, until legitimate business email starts landing in junk folders. Notifications routed to a personal inbox on a public mail provider run the same risk: enough junk, and the filter learns to block you, and real inquiries' notifications quietly vanish.

The mainstream options: filtering, CAPTCHA, honeypots, rate limiting

Mature anti-spam practice for web forms falls into roughly four families, and most sites combine them:

  • Filtering services (content layer). Submissions go to an anti-spam service for a verdict before you accept them. The default answer in the WordPress ecosystem, Akismet, says it is used by millions of websites3; it's everywhere in comment- and message-heavy scenarios.
  • CAPTCHA (interaction layer). A "prove you're human" step before submission. The veteran is Google reCAPTCHA; the newer trend is invisible verification — Cloudflare has replaced every one of its own visual CAPTCHAs with Turnstile, covering challenge pages on over 25 million websites4.
  • Honeypots (form layer). A field invisible to humans that catches scripts which fill in everything. Zero user cost, and a long-standing pick for lightweight setups.
  • Rate limiting (frequency layer). Caps on submission frequency — per-visitor windows and site-wide daily limits, with hard rejection over the cap. Usually stacked on top of the others.

There is no "best family," only a fitting combination: content-heavy forms lean on filtering, forms that can afford one more step use CAPTCHA, and forms that must stay frictionless start with honeypots plus rate limiting.

The order we choose: lightest first

An inquiry form is low-volume but high-value: real submissions are few, and every one matters. So we start with the lightest tools and add weight only if needed.

First gate: the honeypot. It costs almost nothing: no CAPTCHA, no extra second of fill time, no third-party service. It catches the lowest tier of bots — the ones that blindly spray every form on the internet — which is exactly the biggest population. It won't stop a determined attacker; that's what the next gates are for.

Second gate: rate limiting. So many submissions per visitor per time window, and so many per day for the whole site: the first stops targeted abuse, the second backstops your storage. Over the cap, the answer is an explicit "too many requests" — never "we'll take it and sort later." Any tolerance you extend to automated traffic gets used immediately.

The most overlooked weak point: a rate limiter lives or dies not on where you set the threshold, but on who its counter is counting. The "visitor" in the counter must be the actual visitor; if the counter is tracking something that doesn't exist — say, an address that rotates with every request — the most carefully tuned threshold counts nothing. More on that in the next section.

CAPTCHA's two bills: save it for high-value actions

CAPTCHA is the hardest-blocking family in the mainstream lineup, and we don't dispute its effectiveness — but before putting one on an inquiry form, two calculations are worth running.

First, the UX bill. Cloudflare did the math: a CAPTCHA challenge takes a user 32 seconds on average, which across the world's internet users wastes on the order of 500 human years every day5. On an inquiry form, those 32 seconds land squarely on the customer who was trying to reach you.

Second, the channel logic. Anyone who wants to flood a mailbox can simply send email directly and skip the form. A CAPTCHA on the form only stops attackers who insist on using the form — a smaller crowd than you'd think. Put the defense where there's no way around it.

So CAPTCHAs fit best on high-value actions: signup, login, payment, password changes. If honeypot plus rate limiting ever proves insufficient, the next step is invisible verification (Turnstile and its ilk) — far friendlier than the old image puzzles, and the natural first escalation.

Defenses fail silently: installed is not alive

Most software failures are loud: stack traces, crashes, blank pages. You can't miss them. Protections fail the other way — silently. No errors, a perfectly normal page, submissions accepted as usual. Nothing tells you the gate has been standing open.

One common death involves origin addresses. When a site sits behind a CDN or reverse proxy, the "origin address" the application sees is an entire forwarding chain, not the visitor. MDN's documentation for X-Forwarded-For says it plainly: when using this header for security purposes such as rate limiting or access control, trust only the addresses appended by your trusted proxies — otherwise attackers can use it to evade rate limits6. Pick the wrong slot in the chain, and the counter is tracking something that doesn't exist — every submission looks like a new face, and the most precise threshold does nothing.

Worse, a defense can weaken without your knowing: a proxy change, a deployment shuffle, an upstream gateway upgrade — any of these can silently invalidate an assumption that used to be correct. "Verified at launch" is not "still alive today," and whether anything was blocked should never be a feeling. The only trustworthy thing is evidence: read the server-side records, and re-test regularly.

Installing a defense is not the same as having one. Only a real attack can tell you which one you have.

A hardening checklist for small-business inquiry forms

The takeaways, ordered by return on effort:

  1. Honeypot first — zero user cost, kills the largest population of bulk submissions
  2. Rate limiting second — per-visitor window caps and a site-wide daily cap, with explicit rejection; never "we'll take it anyway"
  3. Behind a CDN or reverse proxy, audit how you pick the origin address — count backwards from the end of the chain by the number of trusted proxies; don't reflexively take the first or the last
  4. Save CAPTCHA for high-value actions — on inquiry forms, prefer invisible verification
  5. Attack yourself regularly — fire a burst of submissions, then read the server-side records. A few minutes of work, more reliable than any "should be fine"

Security isn't a feature you finish; it's a habit you keep testing. If you're about to add an inquiry form to your company site — or you're running one that has "never had a problem" — ask it one question: has it ever been hit? That's now a fixed step before we deliver any form.

Was this article helpful?

Questions, corrections, or your own take. We read every piece of feedback.

Let's talk about your project

Most of the problems in this article — we've stepped in them and fixed them ourselves. Arshtech builds web systems, desktop software, and AI-assisted delivery for small businesses, working remotely at a per-project price.