• Lightning Rails
  • Posts
  • How to Avoid Bot Attacks in Rails: Protect Your App from Fake Signups

How to Avoid Bot Attacks in Rails: Protect Your App from Fake Signups

Yesterday, I connected to the admin dashboard of one of my projects, HuntDNA, and saw something shocking: 316 users had signed up! Just last week, the project had zero users since it was still in development. My first reaction? Excitement! But then I started to investigate…

Signs of a Bot Attack in Rails 🤔

The emails looked real—Resend showed good deliverability. But there were no spikes in user activity on Datafast, and neither ChatGPT DeepSearch nor Ahrefs found any backlinks that could explain this sudden surge.

I dug into the logs and soon realized the truth: a bot was signing up random users every 10-20 minutes.

The bot had simply found the /sign_up page and created users in a loop with random passwords.

This is really bad because users started flagging my welcome emails as spam which might hurt deliverability once I launch my app.

How to Prevent Bot Attacks in Rails

  1. Use Email Link Authentication – Users must click a link in their email to verify their identity before their account is created.

  2. Implement Rate Limiting – This prevents bots from repeatedly signing up from the same IP.

  3. Log IP Addresses (Temporarily) – Helps identify attackers and avoid blocking legitimate crawlers like Google’s spiders (which I almost blocked by accident! 😅).

🎛️ Implementing Rate Limiting in Rails with rack-attack

If you’re running a Rails app, adding rate limiting is a crucial step to prevent bot signups and brute force attacks. The rack-attack gem helps throttle excessive requests and block malicious traffic.

Step 1: Add the Gem

First, add rack-attack to your Gemfile:

# Gemfile
gem 'rack-attack'

Then, install it by running:

bundle install

Step 2: Configure rack-attack

Create an initializer file:

touch config/initializers/rack_attack.rb

Open the file and add the following configuration:

class Rack::Attack
  # Limit requests from the same IP to 5 per second
  throttle('req/ip', limit: 5, period: 1.second) do |req|
    req.ip
  end

  # Block IPs that fail authentication too many times
  blocklist('block bad IPs') do |req|
    Rack::Attack::Fail2Ban.filter("bad-ips", maxretry: 5, findtime: 1.minute, bantime: 5.minutes) do
      req.ip if req.path == "/users/sign_in" || req.path == "/users/sign_up" && req.post?
    end
  end

  # Allow whitelisted IPs (e.g., localhost)
  safelist('allow from localhost') do |req|
    '127.0.0.1' == req.ip
  end

  # Log blocked requests
  ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, payload|
    Rails.logger.info "[Rack::Attack] Throttled: #{payload[:request].ip}" if payload[:request]
  end
end

What This Does:

✅ Limits requests to 5 per second per IP

✅ Blocks IPs that exceed 5 failed login attempts in a minute

✅ Allows localhost (127.0.0.1) to bypass limits

✅ Logs blocked requests for monitoring (which helped me avoid blocking Googlebot! 😅)

Step 3: Test Your Configuration

Restart Your Server

rails restart

Monitor Logs

Check if requests are being throttled:

rails s

If a request is blocked, you’ll see something like:

[Rack::Attack] Throttled: 192.168.1.100

Adjust Limits as Needed

  • Increase or decrease request limits based on your traffic.

  • Fine-tune maxretry, findtime, and bantime for login attempts.

  • Add custom rules for protecting specific API endpoints.

Step 4: Deploy and Monitor

Once everything works locally, deploy your changes to production. Monitor logs and adjust as needed.

For high-traffic apps, integrate Redis for better performance.

Checkout Lightning Rails Security documentation for more guides on how to keep your app protected.

Final Thoughts

Bot attacks on Rails apps are more common than you think. By implementing email verification, rate limiting, and IP logging, you can effectively prevent bots from spamming user signups and brute-force attacks.

If you’re running a Rails app, take action today—don’t wait until your database is flooded with fake accounts. 🔒

Happy coding! 🚀

Reply

or to participate.