How to make the honeypot field more effective

How to make the honeypot field more effective

Protect your forms from spam submissions with the honeypot technique

The honeypot field is an antispam technique, a bait form input used to lure spam bots, they'll "see" a field and fill it up with their junk.

This input is hidden from normal users, humans will leave it empty because they won't see it, so it's easy to tell when a form submission is spam or not.

The honeypot will help you catch the majority of the dumb spam bots, however, bots get smarter and harder to trick, so it's not bullet-proof.

<form method="POST" action="form-handler.php">
    <!--  ... form fields ... -->
    <!-- this is the honeypot field -->
    <div style="position: absolute; left: -9999px">
        <label for="website-url">Your website</label>
        <input type="text" id="website-url" name="url" tabindex="-1" autocomplete="nope" />
    </div>
    <!--  ... form fields ... -->
</form>

How to get it right?

Adding a honeypot requires getting your hands dirty with some code, update the form HTML and backend code. Below are my tips on how to make the honeypot more effective and avoid silly mistakes.

1. Make it juicy

Make the field look as legit as possible so even the smarter bots will be tricked into filling it.

✅ set the input type="text" or type="email"

✅ use a common name attribute like email, phone, address, i.e. name="url"

2. Hide it well

Bots get smarter every day, they can recognize honeypot patterns and we don't want that.

❌ don't use type="hidden"

❌ don't use name="honeypot" or another name that would give a hint it's a trap

❌ don't use "display: none" - most bots won't fill the CSS hidden inputs

❌ don't use "hidden" or similar in the class name if you're using that instead of inline styles

✅ Wrap the input & its label in a div tag and position it outside the viewport.

<!-- honeypot field -->
<div class="url-field-wrapper">
    <label for="website-url">Your website</label>
    <input type="text" id="website-url" name="url" tabindex="-1" autocomplete="nope" />
</div>
<!-- the rest of the form -->
.url-field-wrapper {
    position: absolute; 
    left: -9999px;
}

3. Don't shoot yourself in the foot

Browsers have functionalities that can be easily neglected and make legit users get caught by our spam bait input. Yep, false positives. There are 2 input attributes we have to set to avoid:

🚨 set tabindex="-1", tech-savvy visitors will use the tab key to navigate through form fields, if the tabindex attribute is not set they'll be able to focus and accidentally fill in the honeypot

🚨 set autocomplete="nope", avoid browsers' autocomplete feature to fill in the honeypot field, especially when using a common name attribute

4. Fake happiness

If the backend validation fails because the honeypot was filled, don't throw an error, silently discard the submissions and show a success message. Make the spammer think their junk went through.

// require the honeypot field to be present but empty
if(!isset($_REQUEST['url']) || !empty($_REQUEST['url'])) {
    // hello spammer!
    echo 'Thank you for submission!';
}

Additional techniques

As mentioned previously, the honeypot field won't stop all the SPAM submissions but will help to catch at least half of it. If you struggle with spam submissions you'll want to use the honeypot in conjunction with other methods.

The general go-to solution is to add a CAPTCHA, I recommend against it, until it really hurts.

It's effective, but why punish our users because we have a problem with SPAM? It's our problem, not theirs, let's try to address it.

I've had excellent results filtering the form submissions through Akismet, try that before CAPTCHA.

Shameless plug: I run a service that will help you deal with form processing & SPAM protection

👉 POST2