DEV Community

Felippe Regazio
Felippe Regazio

Posted on • Edited on

How to create a simple Honeypot to protect your Forms against Spammers

I think this post will be short and useful. The goal here is to demonstrate a simple technique to help you block spammers and bots that could attack your website forms. This meant to be an extra layer in spam prevention, not the main resource to. Use it with another tools like reCaptcha, etc. Due its simplicity, i really recommend you to follow this form pattern, so, lets code:

Imagine you have the following form structure:

<form id="myformid" action="/myformaction">
    <label for="name">Your Name</label>
    <input type="text" id="name" name="name" placeholder="Your name here" required maxlength="100">
    <label for="email">Your E-mail</label>
    <input type="email" id="email" name="email" placeholder="Your e-mail here" required>
</form>
Enter fullscreen mode Exit fullscreen mode

Most of simple bots will search form common patterns, like label common names, input id's, input common attributes, required fields, etc, and than the bot will fill 'em with fake info to try send you, and your customers, spams or some malicious codes. The most common fields to search are fields named like "email, phone, address"...

So, lets cheat on that and create a simple honeypot by changing our form structure to:


<style>
    .ohnohoney{
        opacity: 0;
        position: absolute;
        top: 0;
        left: 0;
        height: 0;
        width: 0;
        z-index: -1;
    }
</style>

<form id="myformid" action="/myformaction">
    <!-- Real fields -->
    <label for="nameaksljf">Your Name</label>
    <input type="text" id="nameksljf" name="nameksljf" placeholder="Your name here" required maxlength="100">
    <label for="emaillkjkl">Your E-mail</label>
    <input type="text" id="emaillkjkl" name="emaillkjkl" placeholder="Your e-mail here" required>
    <!-- H o n e y p o t -->
    <label class="ohnohoney" for="name"></label>
    <input class="ohnohoney" autocomplete="off" type="text" id="name" name="name" placeholder="Your name here">
    <label class="ohnohoney" for="email"></label>
    <input class="ohnohoney" autocomplete="off" type="email" id="email" name="email" placeholder="Your e-mail here">
</form>
Enter fullscreen mode Exit fullscreen mode

Lets see the changes:

First we created a class to hide things. The .ohnohoney class. Important to point some things now:

  1. Dont use display:none, some bots cant access fields with display none, other simply know that they should'nt fill the display none fields. Dont use "hidden" in the class name, some advanced bots can recognize it.

  2. Than we created the "Real fields". This are the visible fields and the ones which must be relevant to your backend in terms of data. This fields must have the identifications changed to hashes. Commonly i use the pattern "nameHASH" all together. Dont use "name-hash" or variations of that, a simple split would expose the real field name. Now, a bot cant recognize what this fields are, they're just know that the form has some fields which must be filled, maybe following the "type" as pattern.

  3. By creating the "h o n e y p o t" fields we will be able to identify the Spammer. Important to: Let the label empty, use your 'ohnohoney' class to hide all those fake inputs. Turn your fake input the most simple, generic and attractive as possible. Use simple and common names as "email, phone, name, etc", disable the autocomplete (so, browser will not fill it), disable rules, but keep the types.

Now we have 2 parts in our form: Real fields with our inputs protected by hashes and strange names (you can implement the hash or strange names as you prefer). And our honeypot (dont write "honeypot", prefer split the letters to avoid any recognition). Now on your backend:

  1. Verify if any of the "h o n e y p o t" fields came filled. If yes, congrats, you trapped a spam. Most of them will fill all this fields without differentiate them. So, all you have to do is to check if any of your "h o n e y p o t" fields came filled, if yes, its a spam. If you prefer, you can do this check on the client, in case of an ajax form, this will avoid use server resources to compute unuseful data (but keep the backend validation anyway). When you catch a spam, just dont send the data and do whatever you want with it. If names as "email, phone, etc" are important to your backend, just transcript the names using arrays.

Here is a single-file repo with a simple implementation of this technique:
https://github.com/felippe-regazio/php-honeypot-example

Remember: this is just a simple layer to prevent attacks in a simple way, some technologies can identify even this patterns, so use all the weapons you can against it. But i believe that this simple pattern can avoid at least 50% of spams in your webpage.

Latest comments (31)

Collapse
 
tai_studios_ee62ad0ffb40d profile image
TAI Studios

Very interesting technique with the honeypot for dealing with bots in forms, especially because of its simplicity. In my experience, combining this approach with more advanced tools makes a big difference. For example, I recommend Abstract API's honeypot email service, which perfectly complements this type of implementation for greater effectiveness.

Collapse
 
tobias_alvarado_62912c057 profile image
Tobias Alvarado

Can you give us an example about which api did you use?
Thanks mate!

Collapse
 
kcndev profile image
Kachin Developer

Kachin 've been here

Collapse
 
kcndev profile image
Kachin Developer

Kachin have been here

Collapse
 
hasibdevs profile image
Hasibur Rahman

Thanks, It's very helpful technique.

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
delanyoyoko profile image
delanyo agbenyo

I think it's also good to place tabindex="-1" on the honeypot input fields

Collapse
 
delanyoyoko profile image
delanyo agbenyo

Great 👍🏿😃😃👍🏿

Collapse
 
mdazaman profile image
Md A Zaman • Edited

I have implemented honeypot using this technique. Not a single bot could interact so far, great! But the problem is, my real human customers are also facing problem submitting form. Basically messenger web view and chrome are silently auto filling the honeypot fields. Is there any solution to this?

Collapse
 
felipperegazio profile image
Felippe Regazio

This has been a problem, indeed. You can try two techiniques:

1 - stackoverflow.com/questions/157382...
2 - gist.github.com/niksumeiko/3601647...

Let us know if all gone well :D

Collapse
 
yekowele profile image
Yekda

I think, adding autocomplete="off" to ohnohoney inputs might fix the autofill issue. (like lastpass etc.)