When building our new website we came across an issue that is very common in today’s internet - bots sending us messages on our contact form. Our form does not send an email to any of us but rather stores the message to be seen later in our inbox.
Going through the messages that are not related to the business on a daily basis is a waste of time and resources
We initially used the reCaptcha which should
“Protect your site from spam and abuse. It uses advanced risk analysis techniques to tell humans and bots apart.”
Although number of the “bot” messages lowered we were still receiving quite a few - daily. It's understandable as Google's reCaptcha can be found all over the internet and so the efforts of hackers trying to fool it is immense .
Honeypot is not a new idea, but doing it right takes some refinement. This is how we've done it.
To tackle the issue I decided to set up a honeypot for the bots. In the form I included a field that was required and had a value but was not visible to the users. It was visible to bots.
<div class="col-12 form-hp">
<div class="form-group mb-5" >
<label for="phone" class="form-label">Phone</label>
<input name="phone" type="text" value="0" id="phone" class="form-control" autocomplete="haggis-with-onion">
It is as plain and as similar to other fields as possible. There are three differences.
It was visible to the user so I created special class for the field and in this class hidden it for the user. I did not want to use bootstrap class or class with an obvious name since this could be checked by an unwanted guest.
To make it “believable” for the bots to try and change it I called the field “phone”. This created an issue when user used autocomplete, the field was not visible to user but it was there for the browser. I chose something autocomplete was not likely to use and put it in “autocomplete” attribute. This tells browser not to use “phone” which is the id and name of the field and is usually used by browsers unless “autocomplete” attribute is present.
Third difference is the “value” attribute. I needed to check if the field was changed, its not visible to the browser users and it’s not auto-completed with users phone number so if the value is different to the one set by me the message can be flagged as a spam from the “bot”.
So at this point if the field is changed the controller assumes the message was sent by a bot and flags it as a spam message.
How effective was it?
So far at the time of writing this article the solution was implemented for just two months, and hundreds of messages have been flagged as coming from a “bot” upon review we confirmed so far all those messages have rather "spammy" content, most of them not connected to our business.
There were a couple of messages we received that still looked like they were written by a bot but weren’t flagged. It’s possible there was someone pasting the content of the message into our form manually.
Why didn’t we just stop message from sending altogether?
The Honeypot seems to be working well however I decided not to stop flagged messages altogether. Rather than that, they are flagged as “spam” and then being reviewed and mass deleted by a member of the team. This is because there might be cases where user uses a browser that doesn’t support css in which case they would probably fill out the field.