How FormDock filters spam: honeypots, Turnstile, and heuristics
A technical walkthrough of FormDock's three-layer spam stack — and why flagged submissions are quarantined instead of deleted.
Put a form on the public internet and bots will find it within days. Most are crude: they crawl for <form> tags, fill every field, and post. Some are aimed: SEO spam ('buy backlinks'), phishing lures, or junk designed to poison your lead pipeline. A form backend that forwards everything is a spam relay with extra steps — so filtering isn't a feature for us, it's the product working.
FormDock runs three independent layers, each catching a different class of abuse. Here's how each works and why the combination matters.
Layer 1: the honeypot
A honeypot is a field humans never see and bots can't resist. You add a hidden input to your form; crude bots fill every field they find; any submission with a non-empty honeypot is flagged instantly.
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
The details matter: display:none hides it visually, tabindex=-1 keeps keyboard users from landing in it, and autocomplete=off stops browsers from helpfully filling it themselves — the one way a real human 'fails' a honeypot. The field name is configurable per form, because sophisticated bots maintain lists of known honeypot names.
Layer 2: Cloudflare Turnstile
Honeypots stop crude bots; headless-browser bots fill forms like humans do. For those, FormDock supports Cloudflare Turnstile — the CAPTCHA alternative that usually resolves invisibly, without making your users click fire hydrants. Your form includes the Turnstile widget; we verify the token server-side on every submission.
One design decision worth explaining: if Turnstile's verification API is unreachable, we fail open — the submission goes through and the other layers do their best. Failing closed would mean a Cloudflare outage silently discards your real leads, and losing a lead is the one error we treat as unforgivable. Security purists may disagree; we made the trade deliberately and documented it.
Layer 3: content heuristics
The last layer scores the submission's content itself: a vocabulary of spam terms (pharma, casino, 'SEO services', 'guest post'…), link-stuffing (three or more URLs in a message is rarely a genuine lead), and script-mix signatures common in comment spam. Each signal adds to a score; past a threshold, the submission is flagged.
Heuristics are deliberately the softest layer — they're the only one that can produce false positives on legitimate messages, which is why they contribute to a score rather than deciding alone, and why the threshold errs permissive. A real lead wrongly flagged costs more than ten spam messages wrongly passed.
Quarantine, not deletion
Whatever gets flagged is stored anyway — marked as spam, kept out of your notifications, listed in a Spam tab with the reasons ('honeypot', 'keywords: casino', '4 links'). One click marks a false positive as legitimate. This is the never-lose-a-lead principle applied to filtering: the cost of storing spam is a few kilobytes; the cost of silently deleting a real inquiry is a lost customer and your client's trust.
The layer you don't see: rate limiting
Every form also carries a configurable per-minute rate limit. It exists less for you than for the platform: a flooded form can't burn our email sender reputation, which is what keeps notification deliverability high for every other customer. Anti-abuse isn't a nice-to-have for a form relay — it's load-bearing infrastructure.