Throttling Rails logins with Rack Attack

05 Sep 2023

This week, I will show you how to rate-limit your authentication endpoints with Rack Attack.

Rack::Attack is a middleware for blocking or throttling requests based on rules. It uses the configured cache store of Rails to store the necessary data, but a separate data store can be configured too.

In the examples, I will use Devise’s endpoints, but the same setup works with any authentication system, you just need to change the URLs.

Setting up Rack::Attack is very simple, you need to add the gem to your project with bundle add rack-attack.

Once we have the gem installed, we can add our configuration to an initializer, I use config/initializers/rack_attack.rb for that.

To prevent credential stuffing attacks on the login endpoint, you can throttle requests by IP address to a 15 attempts per minute:

class Rack::Attack
  throttle('logins/ip', limit: 15, period: 1.minute) do |req|
    if req.path == '/users/sign_in' && req.post?
      req.ip
    end
  end
end

The throttle call expects the name for the rule and the options as parameters. In the above example, we limit post requests to the /users/sign_in path to 15 per minute for the IP address.

We can harden the configuration even more and add another rule to throttle requests with the same email address:

throttle('logins/email', limit: 10, period: 1.minutes) do |req|
  if req.path == '/users/sign_in' && req.post?
    req.params['user']['email'].to_s.downcase.gsub(/\s+/, "").presence
  end
end

The above rule will throttle login attempts with the same email address to 10 per every minute. This rule prevents brute force attacks.

These two rules will significantly improve the security posture of your Rails app, but depending on your needs, you can introduce additional throttling easily with Rack Attack.

Until next time!

Hire me for a penetration test

Let's find the security holes before the bad guys do.

Did you enjoy reading this? Sign up to the Rails Tricks newsletter for more content like this!

Or follow me on Twitter

Related posts