mirror of
https://github.com/samsonjs/rack-attack.git
synced 2026-04-27 15:07:41 +00:00
Make discriminators case-insensitive by default
This commit is contained in:
parent
8fcd6c8559
commit
a3dff705bb
3 changed files with 57 additions and 3 deletions
|
|
@ -31,7 +31,7 @@ module Rack
|
||||||
autoload :Allow2Ban, 'rack/attack/allow2ban'
|
autoload :Allow2Ban, 'rack/attack/allow2ban'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :enabled, :notifier
|
attr_accessor :enabled, :notifier, :discriminator_normalizer
|
||||||
attr_reader :configuration
|
attr_reader :configuration
|
||||||
|
|
||||||
def instrument(request)
|
def instrument(request)
|
||||||
|
|
@ -79,6 +79,9 @@ module Rack
|
||||||
# Set defaults
|
# Set defaults
|
||||||
@enabled = true
|
@enabled = true
|
||||||
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
||||||
|
@discriminator_normalizer = lambda do |discriminator|
|
||||||
|
discriminator.to_s.strip.downcase
|
||||||
|
end
|
||||||
@configuration = Configuration.new
|
@configuration = Configuration.new
|
||||||
|
|
||||||
attr_reader :configuration
|
attr_reader :configuration
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,7 @@ module Rack
|
||||||
end
|
end
|
||||||
|
|
||||||
def matched_by?(request)
|
def matched_by?(request)
|
||||||
discriminator = block.call(request)
|
discriminator = discriminator_for(request)
|
||||||
|
|
||||||
return false unless discriminator
|
return false unless discriminator
|
||||||
|
|
||||||
current_period = period_for(request)
|
current_period = period_for(request)
|
||||||
|
|
@ -49,6 +48,14 @@ module Rack
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def discriminator_for(request)
|
||||||
|
discriminator = block.call(request)
|
||||||
|
if discriminator && Rack::Attack.discriminator_normalizer
|
||||||
|
discriminator = Rack::Attack.discriminator_normalizer.call(discriminator)
|
||||||
|
end
|
||||||
|
discriminator
|
||||||
|
end
|
||||||
|
|
||||||
def period_for(request)
|
def period_for(request)
|
||||||
period.respond_to?(:call) ? period.call(request) : period
|
period.respond_to?(:call) ? period.call(request) : period
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -144,3 +144,47 @@ describe 'Rack::Attack.throttle with block retuning nil' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'Rack::Attack.throttle with discriminator_normalizer' do
|
||||||
|
before do
|
||||||
|
@period = 60
|
||||||
|
@emails = [
|
||||||
|
"person@example.com",
|
||||||
|
"PERSON@example.com ",
|
||||||
|
" person@example.com\r\n ",
|
||||||
|
]
|
||||||
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||||
|
Rack::Attack.throttle('logins/email', limit: 4, period: @period) do |req|
|
||||||
|
if req.path == '/login' && req.post?
|
||||||
|
req.params['email']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not differentiate requests when discriminator_normalizer is enabled' do
|
||||||
|
post_logins
|
||||||
|
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:person@example.com"
|
||||||
|
_(Rack::Attack.cache.store.read(key)).must_equal 3
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should differentiate requests when discriminator_normalizer is disabled' do
|
||||||
|
begin
|
||||||
|
prev = Rack::Attack.discriminator_normalizer
|
||||||
|
Rack::Attack.discriminator_normalizer = nil
|
||||||
|
|
||||||
|
post_logins
|
||||||
|
@emails.each do |email|
|
||||||
|
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:#{email}"
|
||||||
|
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
Rack::Attack.discriminator_normalizer = prev
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_logins
|
||||||
|
@emails.each do |email|
|
||||||
|
post '/login', email: email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue