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::AttackOr you can use it in Rackup file as
# In config.ru use Rack::AttackBy 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 endHere 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 endAbove 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 endHere, it blocks the request from ‘2.2.2.2’.
Fail2Ban:Fail2Ban.filter
can be used within a blocklist to block all requests from misbehaving clients. Allow2Ban:Allow2Ban.filter
works the same way as theFail2Ban.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' endIn 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" endIt 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.