Skip to content
SheetLink Forms

Spam defense · 2026-07-31 · 8 min read · By Arden Talbot, founder of SheetLink

Honeypots still work

A hidden field invented in the comment-spam era still catches the bulk of automated junk in 2026. That is not nostalgia - it is economics. Here is why, and where the trick genuinely fails.

A ledger-styled illustration of a form with one shaded hidden row acting as a trap, catching a robot's pen while human entries pass into clean columns.

A twenty-year-old trick, still on duty

Spam defense is a field obsessed with novelty - new challenge widgets, new scoring models, new machine-learning claims every quarter. So it sounds contrarian to say that the single most cost-effective layer in a modern stack is a technique from the mid-2000s: an invisible form field that humans never touch and bots reliably fill.

It should not sound contrarian. The honeypot survives for the same reason the lock on your front door survives - it is nearly free, it never inconveniences a legitimate visitor, and it defeats the attacker who is not specifically targeting you, which is almost all of them. This essay makes the case for the honeypot honestly: why it still catches the bulk of automated spam, exactly where it fails, and which layers have to cover those failures.

How it works, in one snippet

A honeypot is an ordinary input, hidden from human eyes with CSS, buried in a normal form:

<form action="https://sheetlinkforms.com/f/your-token" method="POST">
  <input name="email" type="email" required>
  <input name="_slhp" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px">
  <button>Send</button>
</form>

A person filling out the form never sees the field, so it arrives empty. A bot parsing raw HTML sees one more input and fills it, because filling inputs is what it does. Any submission where the trap field carries a value announced its own sender. The logic fits in one conditional, adds zero friction, zero latency, and involves no third party.

A short history of the trap

The idea crystallized during the comment-spam wars of the mid-2000s. Ned Batchelder's 2007 essay on stopping spambots gave the canonical writeup of honeypots alongside hashed field names, and Project Honey Pot, started in 2004, scaled the same instinct into a distributed network of trap addresses used to identify harvesters and spam servers.

Two decades later the technique is embedded in countless form libraries and backends, usually without ceremony. Its longevity is the interesting fact. Defenses that rely on secrecy die when the secret spreads; the honeypot has been publicly documented for twenty years and still works, which tells you its effectiveness rests on something sturdier than obscurity.

Why bots still fall for it

That sturdier thing is economics. The overwhelming majority of form spam comes from breadth-first bots: fetch HTML, find the form, fill every field, POST, next site. They do not execute JavaScript or render CSS, because rendering costs far more compute per page than string-parsing does, and their business model is volume. A bot that renders every page to check field visibility spams fewer sites per dollar than one that does not.

Special-casing your form - writing code to skip the field named _slhp, say - is trivial, but it only pays if your form specifically is worth targeting. For an operator spraying millions of endpoints, per-site customization is exactly the cost their model avoids. The honeypot does not have to be clever. It only has to make the naive strategy fail, because the naive strategy is what the volume runs on.

Hiding the field properly

Implementation details matter more than they look. Position the field off-screen rather than relying only on display:none - checking for display:none is a cheap string match some bots do perform, while computed off-screen positioning requires actual layout. Add tabindex="-1" so keyboard users never focus it, autocomplete="off" so browsers do not helpfully fill it, and aria-hidden so screen readers skip it entirely - a honeypot must never be a trap for people using assistive technology.

Naming is a quiet art: a field called url or phone invites browser autofill into your trap, while something plausible-but-unclaimed reads as just another input to a parser. The SheetLink Forms docs show the exact markup we recommend for static forms.

Where it fails: headless browsers

Now the honest part. A headless browser - Puppeteer or Playwright driving real Chromium - renders your CSS, computes visibility, and fills only the fields a human could see. Against that class of sender, a honeypot is worth nothing. Headless automation used to be expensive enough that spammers rarely bothered; that changed as tooling matured, and targeted campaigns now routinely run full browsers.

Note the qualifier: targeted. Driving a real browser is still an order of magnitude heavier than parsing HTML, so it gets spent on forms worth the spend - or on broad campaigns run by operators with real infrastructure. The honeypot's failure against headless traffic is real, and it is the first reason a honeypot must never be the whole defense.

Where it fails: humans in the loop

The second failure is absolute. Paid form-fill workers - and, increasingly, AI agents driving real browsers - see your page exactly as a customer does. No visibility trick catches a sender who genuinely renders the page, and no field-level trap catches a human being. Scam outreach written and submitted by people passes a honeypot every single time, by definition.

This is worth internalizing because it defines the honeypot's ceiling: it filters the automated bulk, not the motivated minority. The senders it removes are the cheapest ones; the senders it misses are precisely the expensive ones - which is fine, as long as something downstream is watching content and behavior rather than form mechanics. We took apart who those senders are in the anatomy of form spam.

Where it wobbles: the false-positive edge

Honeypots also have a small false-positive surface: overeager browser extensions and form-filler tools occasionally populate every input on a page, hidden or not. It is rare, and the mitigations above - autocomplete="off", off-screen positioning, an unclaimed field name - shrink it further, but rare is not never.

That residual risk shapes policy. In our stack the honeypot is the highest-precision signal we have, and the only one that marks a submission as spam outright rather than sending it to quarantine - but even then the verdict is recorded, not vaporized, consistent with the principle that suspicious submissions are never silently dropped. Precision earns authority; nothing earns invisibility.

The layers that cover the gaps

Map each failure to its cover. Headless scripts that render CSS still tend to submit at machine speed, which the timing signal in our embed catches. Campaigns of any sophistication run into per-form and per-IP rate limits. Human-written spam - immune to every mechanical check - is where content heuristics and quarantine review do the work. And for the sustained, targeted campaign that defeats all passive signals, optional Cloudflare Turnstile raises the gate.

Layered this way, each defense handles the traffic the previous one leaks. The full arrangement, and the reasoning behind review-over-deletion at the end of it, is written up in our spam protection guide and quarantine vs CAPTCHA.

Still the best first layer there is

Judge defenses by return on cost. The honeypot costs one line of markup, no user friction, no latency, no vendor, no privacy questions - and removes the largest single slice of hostile traffic: the breadth-first bots that make up most of what hits a public form. Nothing else in the stack has that ratio.

That is why our embed script auto-injects the honeypot into every form it binds, and why every raw-HTML example in our docs ships with the field included. Twenty years on, the hidden field is not a relic; it is the layer that lets every fancier layer deal only with the remainder. See how it works for where it sits in the pipeline, or watch it do its job against the live demo form.

FAQ

Do honeypots cause accessibility problems?

Not when built correctly. With tabindex="-1", aria-hidden="true", and off-screen positioning, keyboard users and screen readers never encounter the field. A honeypot that a screen reader announces is a bug - the trap must be invisible to assistive technology, not just to eyes.

What should I name the honeypot field?

Something a parser reads as an ordinary input but browser autofill has no claim on - avoid names like email2, url, or phone. Our endpoints use _slhp, and the exact markup is in the docs.

Does the sl.js embed add the honeypot for me?

Yes. The embed auto-injects the honeypot into every form it binds, along with the timing signal, so an embedded form needs no manual markup. Static HTML forms posting directly to an endpoint should include the input themselves: <input name="_slhp" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px">

Can browser autofill accidentally trip a honeypot?

It is the main false-positive risk, and it is small when the field uses autocomplete="off", off-screen positioning, and a name autofill does not recognize. Aggressive form-filler extensions can still occasionally fill everything - one reason verdicts should be recorded rather than silently discarded.

Do honeypots work against AI agents browsing with real browsers?

No. An agent driving a rendered browser perceives the page as a human does and skips invisible fields. That traffic belongs to the layers that judge behavior and content - timing, rate limits, heuristics, and review - not to field-level traps.

What percentage of spam does a honeypot catch?

There is no honest universal number - it depends entirely on how much of your hostile traffic is breadth-first bots versus targeted or human senders. For a typical public form the breadth-first share dominates, which is why the honeypot removes the bulk; a targeted campaign flips that ratio overnight.

Should a honeypot hit hard-block or quarantine?

It is the one signal precise enough to mark spam outright, and that is exactly how we treat it - the only outright verdict in the stack, while every softer signal routes to quarantine for review. The reasoning is laid out in quarantine vs CAPTCHA.

Do I still need a honeypot if I enable Turnstile?

Yes, for the same reason you lock a door inside a gated building: it is free. The honeypot removes naive bots without spending a challenge, a third-party call, or any user attention, leaving Turnstile to gate only the traffic that survives the cheap layers.

Every layer, already wired in

Honeypot auto-injection, timing, rate limits, heuristics, optional Turnstile, and quarantine review on every SheetLink form - free to start.

Start freeSee the live demo

Why silent spam filtering loses customersRate limiting forms: a practical guide