Dev Stories

From “Honey Potter” to Samurai: Why We Forged a Katana to Fight Spam

· 12 min read

Every project has a codename. Some are boring. Ours was embarrassing.

We called it “Honey Potter.”

Yes, like the wizard. No, we are not proud of it. The name started as a throwaway joke in a group chat — someone mashed “honeypot” and “Harry Potter” together, and it stuck. Before we knew it, our Git branches said honey-potter/feature-xyz, our Slack channel was #honey-potter-dev, and our internal docs had a wand emoji (🪄) next to every milestone.

The metaphor was actually kind of perfect, though. We wanted to build something magical. A simple spell — a honeypot — that would make spam disappear without anyone noticing. Wave the wand, cast the charm, problem solved.

What we did not realize at the time was that the dark arts had leveled up considerably. And a first-year charm was not going to cut it.

This is the plugin development story behind Samurai Honeypot for Forms — how a joke codename turned into a serious anti-spam engine, and every wrong assumption we made along the way.


The Origin Story

It Started with a Phone Call

It was a Monday morning. The office had barely opened when the phone rang.

A client was on the line. “Half of our inquiries this week were just spam,” they reported. “It’s getting annoying to sift through them.” Almost all of their legitimate inquiries came from within Japan, but 99% of the spam was from overseas senders. Foreign-language messages, foreign IP addresses, foreign everything.

We tried something quick first: a quiz question on the form that only someone living in Japan could answer. It worked — spam dropped to near zero overnight. But the client’s marketing team pushed back. A sudden trivia question in the middle of a polished contact form ruined the UX. And with LLMs getting smarter by the month, we knew this cultural hurdle had an expiration date.

So we looked at the broader ecosystem. reCAPTCHA v3 helped a little but flagged legitimate users on VPNs. Akismet caught some of the junk, but missed the clever AI-generated spam. Furthermore, we wanted to maintain a strict standard of data privacy, which meant we actively wanted to avoid solutions that send submission data to third-party APIs. Simple honeypot plugins worked for about a week before the bots learned to skip the hidden fields.

We could have tried running multiple plugins simultaneously, but the maintenance burden of duct-taping them together just to protect a contact form was absurd. Nothing stuck. Every tool we tried was either fighting the last war or creating new problems like performance hits and UX degradation.

So we did what developers always do when existing tools let them down: we opened a new repo and decided to build it ourselves. But if we are being completely honest, there was another reason: we just really wanted to build it. We were tired of managing third-party updates. The challenge of creating a standalone, elegant defense mechanism from scratch sounded like a fun engineering problem to solve.

The “Just a Honeypot” Phase

The first version of Honey Potter was exactly what the name implied. A honeypot. One hidden field, injected into Contact Form 7, checked on the server side. If the field had a value, reject the submission. Classic.

We wrote it in an afternoon. It was maybe 80 lines of PHP. We shipped it to a test site, saw the absolute volume of spam drop drastically, and felt very clever about ourselves.

But we only got to feel clever for eleven days.

To be clear, the plugin did not suddenly break on day twelve. The dumb, low-effort curl scripts were still getting blocked, and the overall volume remained down. But as we looked closer at the logs, we realized what was slipping through: the headless browser bots.

These bots, running real Chromium instances, walked right past our honeypot like it was not there. They checked getComputedStyle, saw the field was hidden, skipped it, and submitted clean-looking spam that sailed through our filter. The quantity of spam was down, but the high-quality spam was still polluting the signal-to-noise ratio.

Seeing those high-effort bots casually bypass our filter did not just annoy us—it ignited our engineer egos. “We reduced the volume. If we try harder, we can catch these smart ones too!” If we had been satisfied with just “reducing” spam, the story would have ended there. But that pure technical obsession to completely eradicate the problem pushed us straight into the next phase.

The Over-Engineering Phase

Driven by the desire to catch every single bot, we happily fell into the classic developer trap: over-engineering.

The second prototype had machine learning scoring, canvas fingerprinting, and a local SQLite database for tracking bot signatures. We were convinced that the way to beat smart bots was with an even smarter system.

It worked well in testing. It was a nightmare in production. The ML model needed training data we did not have. The fingerprinting broke on Safari. The SQLite database grew silently until it ate disk space. When something went wrong — and it often did — debugging required understanding three different subsystems simultaneously.

We scrapped it and went back to basics. The lesson was clear: the best security tools are boring on the inside. Boring code is reliable code. The cleverness should be in the architecture, not the implementation.


The Reality Check

Simple Magic Is Not Enough

Here is the uncomfortable truth we had to accept: a traditional honeypot, by itself, is a solved problem. Not solved by us — solved by the bots.

Any bot running a headless browser can detect hidden form fields. The CSS tricks that worked in 2015 — display: none, opacity: 0, off-screen positioning — are all one-line JavaScript checks for a modern bot. The field name is static, the hiding method is static, the position in the DOM is static. A bot author reverse-engineers your form once and writes a bypass that works forever. Many sites around the world are relying on these powerless defenses.

We were casting a first-year spell against seventh-year dark wizards. (Sorry, the Honey Potter metaphor dies hard.)

The problem was not honeypots as a concept. The problem was that our honeypot was predictable. Same field, same name, same hiding, every single page load. We had built a lock and then handed out copies of the key.

The Moment Everything Changed

The turning point came when we ran a logging experiment on one of our test sites. We instrumented the form to record everything: submission timing, field population order, whether JavaScript had executed, whether mouse events had fired, the works.

After a week, we had data on thousands of submissions. And the patterns were striking:

  • 87% of spam submissions arrived in under 2 seconds. Humans took 15-45 seconds.
  • 94% of spam had zero mouse movement events. Even keyboard-only users generate some pointer activity on mobile.
  • 100% of spam that bypassed our honeypot came from bots that evaluated CSS before filling fields.
  • A growing chunk of messages were grammatically perfect, contextually relevant, and clearly generated by a language model.

That data changed how we thought about the problem entirely. We were not dealing with one type of attacker. We were dealing with a wide spectrum — from braindead curl scripts to AI-powered agents — and a single defense layer could never cover all of them.

We did not just need a better spell. We needed a katana.

From Charm to Katana

This is where the Honey Potter metaphor completely dies. A honeypot is a trap. It is passive. It waits for the bot to make a mistake. But what if the bot does not make that mistake?

We realized we did not just need a passive shield to hide behind. We needed an active weapon. Something that evaluates every request, checks multiple signals, trusts nothing from the client side, and ruthlessly cuts down anything that does not act human. We were forging a blade.

We moved from a single-trick trap to an active, multi-layered defense system. Here are the strikes we added to our stance:

Layer 1: Polymorphic honeypots. Instead of one static hidden field, we generate fields with randomized names and randomized CSS hiding strategies on every page load. The form constantly changes its shape, leaving the attacker nothing to study or memorize.

Layer 2: Timing analysis. We embed a signed timestamp when the form renders and check the elapsed time on submission. Anything under 3 seconds is almost certainly automated. It is trivially simple, but it catches a surprising amount of spam.

Layer 3: Client-side proof of work. The browser has to solve a small computational puzzle before the form can submit. It takes a human’s browser a few hundred milliseconds — invisible to the user. But for a bot trying to submit thousands of forms, that computational cost adds up fast.

Layer 4: Stateless HMAC tokens. Every form carries a cryptographic token generated server-side. No token, no submission. The token is stateless (no database, no session) so it survives aggressive page caching and CDN setups without breaking.

Layer 5: Silent rejection. When we catch a bot, we do not tell it. We return a fake success message. The bot thinks it won and moves on. By cutting off the feedback loop, we deny bot operators the signals they need to evolve.

Each layer alone is imperfect. Together, they cover each other’s blind spots. A bot smart enough to skip the honeypot still gets cut down by the timing check. A bot that adds an artificial delay still cannot solve the proof of work fast enough at scale. A bot that handles all of the above still does not have a valid HMAC token if it forged the request.

Defense in depth is not a buzzword. It is the only strategy that realistically holds.


The Result

What Honey Potter Became

That goofy codename eventually became Samurai Honeypot for Forms — a production-grade anti-spam plugin for Contact Form 7.

The name lost the wizard reference (our marketing instincts are slightly better than our naming instincts), and a Samurai took its place. At its core, it is still a honeypot, but it evolved from a passive jar of honey into an active, adapting, multi-layered defense system.

Here is what the plugin does, in plain terms:

  • Polymorphic honeypot fields with dynamic names and randomized CSS hiding. No two page loads look the same to a bot.
  • Submission timing validation to catch bots that fill forms faster than any human could.
  • Client-side proof of work that is invisible to users but expensive for bots at scale.
  • Stateless HMAC tokens that work behind CDNs and page caches without breaking.
  • Silent failure mode that never tips off the bot that it was caught.
  • Zero configuration. Install, activate, done. No API keys, no account signups, no settings pages to fiddle with.
  • No cookies, no external requests. Built to protect data privacy by design, keeping all processing on your own server.
  • Full accessibility. Screen readers, keyboard navigation, and assistive devices are all handled properly with aria-hidden and tabindex attributes.

What We Learned Building It

Every plugin development story has lessons. Here are ours.

Start with data, not assumptions. We assumed a honeypot would be enough because it used to be enough. The logging experiment showed us how wrong we were. If we had been satisfied with our first version, we would have shipped a plugin that only blocked the lowest-effort bots while leaving users completely vulnerable to the truly annoying spam.

The bot ecosystem is a spectrum. You are not fighting a single “bot.” You are fighting curl scripts, headless browsers, and AI agents simultaneously. A defense that stops one type and ignores the others gives you a false sense of security.

Statelessness matters more than you think. Early versions of our token system used WordPress transients. It worked in development and broke immediately on any site running a page cache. Moving to stateless HMAC tokens solved the problem permanently and ensured compatibility with every caching setup we tested.

Silent failure is the most underrated technique in anti-spam. The moment you return a 403 or an error message, you are training the attacker. A fake 200 response with a “thank you” message gives the bot zero information about whether its approach is actually working.

WordPress plugin development is a user experience problem, not just a code problem. Users do not want to configure complex settings pages. They want to install a plugin and have it work. For every setting we considered adding, we asked: “Can we just pick the right default?” Almost always, the answer was yes.

The Codename Lives On

Internally, we still call it Honey Potter sometimes. Old habits. The Slack channel was never renamed, and the original Git branch prefix still shows up in our history if you look far enough back.

It is a good hook to remind us of where we started: an arrogant team that thought spam was a simple problem with a simple solution. The name keeps us humble. Every time someone on the team says “isn’t this feature enough?” someone else replies with, “Remember when we thought a single honeypot was enough?”

And then we go back to sharpening the blade.


Key Takeaways

  1. A traditional honeypot is necessary but not sufficient. It catches low-effort bots, which are still the majority by volume. But it is completely powerless against anything running a headless browser.

  2. Modern bot defense requires multiple layers. Polymorphic fields, timing checks, proof of work, cryptographic tokens, and silent failure — each one covers the gaps in the others.

  3. Ship with sensible defaults. The best security plugin is one that works the moment you activate it. Excessive configuration is a barrier, not a feature.

  4. Never give the attacker feedback. Silent rejection removes the signals that drive bot evolution.

  5. Start with data. Log, measure, analyze. Your assumptions about what is hitting your forms are probably wrong. Just like ours were.

If you run Contact Form 7 and you are tired of spam, give Samurai Honeypot for Forms a try. It is free, requires zero setup, and was built by a team that learned the hard way that simple magic is not enough.

We just had to pass through the “Honey Potter” phase to figure that out.

All Columns