metamaps--metamaps/config/initializers/rack-attack.rb

62 lines
2.1 KiB
Ruby
Raw Normal View History

2016-12-13 03:28:10 +00:00
# frozen_string_literal: true
class Rack::Attack
2016-09-25 15:21:51 +00:00
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
2016-09-25 15:21:51 +00:00
# Throttle all requests by IP (60rpm)
#
# Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}"
# throttle('req/ip', :limit => 300, :period => 5.minutes) do |req|
# req.ip # unless req.path.start_with?('/assets')
# end
2016-09-25 15:21:51 +00:00
# Throttle POST requests to /login by IP address
#
# Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}"
2016-12-13 03:28:10 +00:00
throttle('logins/ip', limit: 5, period: 20.seconds) do |req|
req.ip if req.path == '/login' && req.post?
2016-09-25 15:21:51 +00:00
end
# Throttle POST requests to /login by email param
#
# Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{req.email}"
#
2016-09-25 15:21:51 +00:00
# Note: This creates a problem where a malicious user could intentionally
# throttle logins for another user and force their login requests to be
# denied, but that's not very common and shouldn't happen to you. (Knock
# on wood!)
2016-12-13 03:28:10 +00:00
throttle('logins/email', limit: 5, period: 20.seconds) do |req|
2016-09-25 15:21:51 +00:00
if req.path == '/login' && req.post?
# return the email if present, nil otherwise
req.params['email'].presence
end
end
2016-12-13 03:28:10 +00:00
throttle('load_url_title/req/5mins/ip', limit: 300, period: 5.minutes) do |req|
req.ip if req.path == 'hacks/load_url_title'
end
2016-12-13 03:28:10 +00:00
throttle('load_url_title/req/1s/ip', limit: 5, period: 1.second) do |req|
2016-09-25 15:21:51 +00:00
# If the return value is truthy, the cache key for the return value
# is incremented and compared with the limit. In this case:
# "rack::attack:#{Time.now.to_i/1.second}:load_url_title/req/ip:#{req.ip}"
#
# If falsy, the cache key is neither incremented nor checked.
req.ip if req.path == 'hacks/load_url_title'
end
self.throttled_response = lambda do |env|
2016-12-13 03:28:10 +00:00
now = Time.now
match_data = env['rack.attack.match_data']
2016-09-25 15:21:51 +00:00
period = match_data[:period]
limit = match_data[:limit]
2016-12-13 03:28:10 +00:00
headers = {
2016-09-25 15:21:51 +00:00
'X-RateLimit-Limit' => limit.to_s,
2016-12-13 03:28:10 +00:00
'X-RateLimit-Remaining' => '0',
'X-RateLimit-Reset' => (now + (period - now.to_i % period)).to_s
}
2016-09-25 15:21:51 +00:00
[429, headers, ['']]
end
end