Example from README:
limit_proc = proc { |req| req.env["REMOTE_USER"] == "admin" ? 100 : 1 }
period_proc = proc { |req| req.env["REMOTE_USER"] == "admin" ? 1 : 60 }
Rack::Attack.throttle('request per ip', limit: limit_proc, period: period_proc) do |request|
request.ip
end
In my specific case, I have a dynamic limit that's based on whether an IP is recognized as VPN, DC, Tor, specific country, etc. Presence of each indicator increases the penalty. For example: VPN x3, Russia 2x, DC x3, and VPN+Russia would be x5. To simplify it for this issue description, consider it something like this:
limit_proc = proc do |req|
factors = {}
if Geocoder.country(req.remote_ip) == 'us'
factors[:country] = 2
end
if SecurityChecker.vpn?(req.remote_ip)
factors[:vpn] = 3
end
penalty = factors.values.sum
(60.0 / penalty).ceil
end
Rack::Attack.throttle('request per ip', limit: limit_proc, period: 60) do |request|
request.ip
end
When a throttle trips, all I'll know is that the limit was 60, or 30, or 20, or 10.. It can be any number that comes out. Wouldn't it be great to retain the value of factors variable somehow, so notifications and throttle request handler can access it in env['rack.attack.match_data'] or alike?
For example:
limit_proc = proc do |req|
factors = {}
if Geocoder.country(req.remote_ip) == 'us'
factors[:country] = 2
end
if SecurityChecker.vpn?(req.remote_ip)
factors[:vpn] = 3
end
penalty = factors.values.sum
limit = (60.0 / penalty).ceil
[limit, factors]
# will return: [5, {country: 2, vpn: 3}
# ^ throttle uses this as the limit
#. ^ this contextual information lands in rack.attack.match_data if this throttle trips
end
What do you think?
Example from README:
In my specific case, I have a dynamic
limitthat's based on whether an IP is recognized as VPN, DC, Tor, specific country, etc. Presence of each indicator increases the penalty. For example: VPN x3, Russia 2x, DC x3, and VPN+Russia would be x5. To simplify it for this issue description, consider it something like this:When a throttle trips, all I'll know is that the limit was 60, or 30, or 20, or 10.. It can be any number that comes out. Wouldn't it be great to retain the value of
factorsvariable somehow, so notifications and throttle request handler can access it inenv['rack.attack.match_data']or alike?For example:
What do you think?