Rack::Attack – secure you rails app for the real world

Are you worried about the security issues in your Rails app? The rack-attack gem, can help you. Rack::Attack is a rack middleware which provides security to our rails application. It allows us to safelist, blacklist, throttle and to track requests.

  • If the request matches any safelist, it is allowed.
  • If the request matches any blocklist, it is blocked.
  • If the request matches any throttle, a counter is incremented in the Rack::Attack.cache. If any throttle’s limit is exceeded, the request is blocked.
  • Otherwise, all tracks are checked, and the request is allowed.

Implementation

Install the rack-attack gem, or add it to you Gemfile as:
gem 'rack-attack'
Then tell your app to use the Rack::Attack middleware. For Rails 3+ apps:
# In config/application.rb
config.middleware.use Rack::Attack
Or you can use it in Rackup file as
# In config.ru
use Rack::Attack
By default, Rack Attack uses Rails cache. You can override that by setting the `Rack::Attack.cache.store` value. It is used for throttling. If you want to create use a custom adapter, for example, memory store,  create a file called rack_attack.rb in config/initializers to configure Rack Attack and put the following code in the file:
class Rack::Attack
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
  ########
end

Throttle

throttle('api/ip', limit: 3, period: 10) do |req|
  req.ip
end
Here we are limiting the request per seconds from the same IP address. Here we are limiting only 3 requests in 10 sec.

Safelist

Rack::Attack.safelist('allow from localhost') do |req|
  '127.0.0.1' == req.ip
end
Above example always allows the request from localhost. And the request is allowed if the value is true.

Blacklist

Rack::Attack.blacklist('block 2.2.2.2') do |req|
  '2.2.2.2' == req.ip
end
Here, it blocks the request from ‘2.2.2.2’.
Fail2BanFail2Ban.filter can be used within a blocklist to block all requests from misbehaving clients. Allow2Ban: Allow2Ban.filter works the same way as the Fail2Ban.filter except that it allows requests from misbehaving clients until such time as they reach maximum retry.

Block logins from a bad user agent

Rack::Attack.blacklist('block bad UA logins') do |req|
  req.path == '/login' && req.post? && req.user_agent == 'BadUA'
end
In the above example, if a bad user tries to login, the request is blocked.

Tracks

Rack::Attack.track("special_agent") do |req|
  req.user_agent == "SpecialAgent"
end
It tracks request from a special user.

Security issues that Rack Attack addresses

  • Rate limits against DDoS and abusive users

DDoS is short for Distributed Denial of Service. It uses multiple computers and Internet connections to flood the targeted resource.

When you need more security to your rails app, don’t forget to add Rack::Attack in it. It will protect your app from bad clients.

Whitelist Search Engine spiders

        Though we blacklist IP’s that are misbehaving, we have to whitelist search engine spiders. But they have a huge range of IP’s. So we can check user agent. But it’s something anyone can fake. We can run a reverse DNS lookup of the accessing IP and perform a forward DNS lookup on the domain (using host command). Verify that it is same as the original IP address from the logs.

References

]]>