Honeypots, A Lightweight Bot Defense Strategy

Honeypots: A Lightweight Bot Defense Strategy

Introduction

  • A honeypot, in the context of web security, is a trap designed to attract and detect malicious automated software (bots). It’s essentially a hidden field in a form that is invisible to human users but is often filled in by bots that blindly fill all form fields. If the honeypot field is populated, it’s a strong indicator that the submission is from a bot, allowing you to reject it.

  • Honeypots allow your application to ignore spambots without forcing your users to fill out a captcha or jump through other hoops to fillout your form

  • This is done by adding a hidden field only visible to spambots. This field helps admin identify whether the user is a spambot and not a user

Benefit:

  • Lightweight and User-Friendly: Unlike CAPTCHAs, honeypots don’t add friction for legitimate users.
  • Effective Against Basic Bots: They effectively block simple bots that blindly fill all form fields.
  • Simple Implementation: Relatively easy to implement in web forms.

Illustration:

Imagine a form with fields like “Email,” “Password,” and a hidden field labeled “Nickname” (our honeypot). A human user won’t see or interact with “Nickname.” However, a bot, programmed to fill all fields, will fill it. If the “Nickname” field has data, it indicates a likely bot submission.

<form>
  <label for="email">Email:</label>
  <input type="email" id="email" name="email"><br><br>

  <label for="password">Password:</label>
  <input type="password" id="password" name="password"><br><br>

  <div style="display:none;">
    <label for="nickname">Leave this field blank:</label>
    <input type="text" id="nickname" name="nickname" autocomplete="off">
  </div>

  <input type="submit" value="Submit">
</form>

✅ 1. Add the Honeypot Field in Your Devise Registration Form

Edit:

# app/views/devise/registrations/new.html.erb
<div style="display:none;">
  <%= f.label :nickname, "Leave this field blank" %>
  <%= f.text_field :nickname, autocomplete: "off" %>
</div>

Here, :nickname is the honeypot field. autocomplete: "off" is added to help prevent browser’s autofill features from accidentally filling the honeypot.

✅ 2. Permit the Honeypot Param in Your Controller

In application_controller.rb:

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end

This ensures that the nickname parameter is allowed in the form submission.

✅ 3. Add Honeypot Validation to Your User Model

In user.rb:

validate :nickname_should_be_blank

def nickname_should_be_blank
  errors.add(:base, "Bot detected") unless nickname.blank?
end

This validation checks if the nickname field is empty. If it’s not, an error is added, and the registration fails.

✅ 4. Add the nickname Column to the Users Table

In your terminal:

rails generate migration AddNicknameToUsers nickname:string
rails db:migrate

If you don’t want to store it, you can use attr_accessor instead of a DB column:

attr_accessor :nickname

In this case, no DB migration is needed. Perfect for pure honeypot use.

✅ 5. (Optional) Add Server-Side Logging for Bots

In your model:

def nickname_should_be_blank
  if nickname.present?
    Rails.logger.warn "🚨 Bot detected during sign up: IP #{request.remote_ip}" rescue nil
    errors.add(:base, "Bot detected")
  end
end

Or trigger an event, email, or anything you want.

⚠️ Problems You May Face

  • Advanced Bots: Sophisticated bots might be programmed to detect and avoid honeypots.
  • Accidental Human Interaction: Although rare, a user with accessibility needs or a very unusual browser setup could accidentally fill the hidden field.
  • Browser Autofill: some browser autofill features may accidently fill the hidden field. The autocomplete=”off” attribute helps, but isn’t a perfect solution.

🛠️ Alternative Solutions

  • CAPTCHA/reCAPTCHA: Provides a more robust defense against bots but can be intrusive to users.
  • Rate Limiting: Limits the number of registration attempts from a single IP address, preventing brute-force attacks.
  • Behavioral Analysis: Analyzes user behavior to detect bot-like patterns.
  • Double Opt-In: Requires users to confirm their email address, ensuring they are real.
  • Javascript challenges: Require javascript to be run to submit the form, which blocks many simple bots.

References

🎯 Done!

Real users won’t see the field, bots will likely fill it in, and your app quietly blocks them. Remember to complement this with other security measures for comprehensive protection.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • How to set up live reloading Golang
  • Running LLMs Locally with Open Web UI and Ollama
  • Google Kubernetes Engine
  • Intro to GCP Cloud Shell and gcloud
  • Creating A Build Tool Using Go