Rafał Jaroszewicz

Create honeypot against spam bots in Rails

Funny captcha presenting winter forest with task to select all finnish snipers.
I was trying to implement something that is less annoying than google recaptcha. Everyone knows that it’s quite exhausting for some users. Also I would like to reduce the amount of requests made to google with all gtags, analytics, ads etc. are already slowing the whole internet down.
I found this very old article on how to stop those simpliest bots(in the app I am working on most of the spam came from these basic crawler/spammer types) using a honeypot technique.
Basically whole idea behind honeypot is that you can add some fields to the form that are not visible to the user, but if those simple bots scraping your website will see them, they would probably fill them out.
This article inspired me to try it with a little twist, and here’s how it went.
Of course this will be of no use against real human spammers. So you should probably also invest in Akismet.

Let’s add some of these strategies mentioned in the article into the controller that is responsible for creating Posts.

# clarify time will make more sense later on. I am using regular names like status and street_name for my trap fields, they will be invisible to the user anyway, but bots might have a list of fields to fill out.
Notice how I send status: :ok when the alert is shown(means it got caught either by timer or by filling the field that should be empty). So for normal human being nothing will really change, but bot will see response 200 OK meaning that he was successful in his posting and will move on.
You should also consider adding blocking IP’s after certain amount of tries within short period of time. I have noticed that these bots usually send hundreds of requests/sec, so these should be relatively easy to catch.
You can easily test it as well.

Now, let’s create a partial that will be used in our views for rendering this honeypot using <%= render 'posts/honeypot' %> later on.

#general-ackbar { display: none;} will hide out our div, but I am still using css_strategy to change it as I assume some bots might read css and just ignore some of the fields if they’re for example hidden. These are just some ways to obfuscate your fields.
Now, I also obfuscate the time so I can check it once it gets back to the server. In the previous gist you saw that timer is set to 5 seconds.
This can be just changed to any number, just try to fill out your form as fast as you can and then add this time as a value under which you will display the alert.

To summarize, this method will not protect against any advanced bots and human spammers, but it might help you fight those basic robots.
You might also want to add blocking IP’s that are sending too many requests and other anti-spam tools.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top