rack-attack 6.3.1 → 6.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3735d065000def3fce68a51f86fd46eec60d8ce8aac80991bd4c1fd05cf2babd
4
- data.tar.gz: def7883dbc56f61163d54104e6a9b1aa87a93f47cdfefe60bb81880a7237aa8b
3
+ metadata.gz: 81f6cce465b8441782ffaa3d446e558979de6a2ceadd9d43499b7977fa61586b
4
+ data.tar.gz: a2ee9b82f1144d483e7d26a893594ab6cada4dc52d98eb08d7615a38b49face8
5
5
  SHA512:
6
- metadata.gz: 4c40ef6a1a7f2c1692b5bf3c46cb4f7e25bec5f413c9f96ee8b37b62e67b9f2e31e3c8067c9ecf19af4be16bbc01e016a3921052ed08c42c8a72b8a7696653e1
7
- data.tar.gz: 3bb4d54e791d056a5e905e72b325a1eb733a6f3b660601f4d4ac39aa1b46cf480879bfae72575ce8ed8420961166ef3273cbe3590f60efa552946fbfb20cd7c2
6
+ metadata.gz: b90fa7841d1e5319b820d4bca9c1fc8d266fc98c06f2a936ce6d31949d9fdd7ddab9183f82c5bbbc31e3e4280bba8e786bbe155f146fdcfdbf53ad263bfec63f
7
+ data.tar.gz: c91be495fbf25444632a1734f40f9fa85b35bf19d921a129ca402aceadf0d30b2a7d5797283ca7ac68e8f323569fa3edc1be98bcecd2c72aa15c3956dd611455
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  __Note__: You are viewing the development version README.
2
- For the README consistent with the latest released version see https://github.com/kickstarter/rack-attack/blob/6-stable/README.md.
2
+ For the README consistent with the latest released version see https://github.com/rack/rack-attack/blob/6-stable/README.md.
3
3
 
4
4
  # Rack::Attack
5
5
 
@@ -10,7 +10,7 @@ Protect your Rails and Rack apps from bad clients. Rack::Attack lets you easily
10
10
  See the [Backing & Hacking blog post](https://www.kickstarter.com/backing-and-hacking/rack-attack-protection-from-abusive-clients) introducing Rack::Attack.
11
11
 
12
12
  [![Gem Version](https://badge.fury.io/rb/rack-attack.svg)](https://badge.fury.io/rb/rack-attack)
13
- [![Build Status](https://travis-ci.org/kickstarter/rack-attack.svg?branch=master)](https://travis-ci.org/kickstarter/rack-attack)
13
+ [![Build Status](https://travis-ci.org/rack/rack-attack.svg?branch=master)](https://travis-ci.org/rack/rack-attack)
14
14
  [![Code Climate](https://codeclimate.com/github/kickstarter/rack-attack.svg)](https://codeclimate.com/github/kickstarter/rack-attack)
15
15
  [![Join the chat at https://gitter.im/rack-attack/rack-attack](https://badges.gitter.im/rack-attack/rack-attack.svg)](https://gitter.im/rack-attack/rack-attack)
16
16
 
@@ -40,7 +40,6 @@ See the [Backing & Hacking blog post](https://www.kickstarter.com/backing-and-ha
40
40
  - [Testing](#testing)
41
41
  - [How it works](#how-it-works)
42
42
  - [About Tracks](#about-tracks)
43
- - [Testing](#testing)
44
43
  - [Performance](#performance)
45
44
  - [Motivation](#motivation)
46
45
  - [Contributing](#contributing)
@@ -72,12 +71,7 @@ Or install it yourself as:
72
71
 
73
72
  Then tell your ruby web application to use rack-attack as a middleware.
74
73
 
75
- a) For __rails__ applications with versions >= 5.1 it is used by default. For older rails versions you should enable it explicitly:
76
- ```ruby
77
- # In config/application.rb
78
-
79
- config.middleware.use Rack::Attack
80
- ```
74
+ a) For __rails__ applications it is used by default.
81
75
 
82
76
  You can disable it permanently (like for specific environment) or temporarily (can be useful for specific test cases) by writing:
83
77
 
@@ -141,7 +135,7 @@ E.g.
141
135
  # Provided that trusted users use an HTTP request header named APIKey
142
136
  Rack::Attack.safelist("mark any authenticated access safe") do |request|
143
137
  # Requests are allowed if the return value is truthy
144
- request.env["APIKey"] == "secret-string"
138
+ request.env["HTTP_APIKEY"] == "secret-string"
145
139
  end
146
140
 
147
141
  # Always allow requests from localhost
@@ -264,10 +258,12 @@ Rack::Attack.throttle("requests by ip", limit: 5, period: 2) do |request|
264
258
  end
265
259
 
266
260
  # Throttle login attempts for a given email parameter to 6 reqs/minute
267
- # Return the email as a discriminator on POST /login requests
261
+ # Return the *normalized* email as a discriminator on POST /login requests
268
262
  Rack::Attack.throttle('limit logins per email', limit: 6, period: 60) do |req|
269
263
  if req.path == '/login' && req.post?
270
- req.params['email']
264
+ # Normalize the email, using the same logic as your authentication process, to
265
+ # protect against rate limit bypasses.
266
+ req.params['email'].to_s.downcase.gsub(/\s+/, "")
271
267
  end
272
268
  end
273
269
 
@@ -343,7 +339,7 @@ end
343
339
  While Rack::Attack's primary focus is minimizing harm from abusive clients, it
344
340
  can also be used to return rate limit data that's helpful for well-behaved clients.
345
341
 
346
- If you want to return to user how many seconds to wait until he can start sending requests again, this can be done through enabling `Retry-After` header:
342
+ If you want to return to user how many seconds to wait until they can start sending requests again, this can be done through enabling `Retry-After` header:
347
343
  ```ruby
348
344
  Rack::Attack.throttled_response_retry_after_header = true
349
345
  ```
@@ -378,7 +374,7 @@ Rack::Attack uses the [ActiveSupport::Notifications](http://api.rubyonrails.org/
378
374
 
379
375
  You can subscribe to `rack_attack` events and log it, graph it, etc.
380
376
 
381
- To get notified about specific type of events, subscribe to the event name followed by the `rack_attack` namesapce.
377
+ To get notified about specific type of events, subscribe to the event name followed by the `rack_attack` namespace.
382
378
  E.g. for throttles use:
383
379
 
384
380
  ```ruby
@@ -401,6 +397,10 @@ end
401
397
 
402
398
  ## Testing
403
399
 
400
+ A note on developing and testing apps using Rack::Attack - if you are using throttling in particular, you will
401
+ need to enable the cache in your development environment. See [Caching with Rails](http://guides.rubyonrails.org/caching_with_rails.html)
402
+ for more on how to do this.
403
+
404
404
  ### Disabling
405
405
 
406
406
  `Rack::Attack.enabled = false` can be used to either completely disable Rack::Attack in your tests, or to disable/enable for specific test cases only.
@@ -445,13 +445,6 @@ can cleanly monkey patch helper methods onto the
445
445
 
446
446
  `Rack::Attack.track` doesn't affect request processing. Tracks are an easy way to log and measure requests matching arbitrary attributes.
447
447
 
448
-
449
- ## Testing
450
-
451
- A note on developing and testing apps using Rack::Attack - if you are using throttling in particular, you will
452
- need to enable the cache in your development environment. See [Caching with Rails](http://guides.rubyonrails.org/caching_with_rails.html)
453
- for more on how to do this.
454
-
455
448
  ## Performance
456
449
 
457
450
  The overhead of running Rack::Attack is typically negligible (a few milliseconds per request),
data/lib/rack/attack.rb CHANGED
@@ -6,6 +6,12 @@ require 'rack/attack/cache'
6
6
  require 'rack/attack/configuration'
7
7
  require 'rack/attack/path_normalizer'
8
8
  require 'rack/attack/request'
9
+ require 'rack/attack/store_proxy/dalli_proxy'
10
+ require 'rack/attack/store_proxy/mem_cache_store_proxy'
11
+ require 'rack/attack/store_proxy/redis_proxy'
12
+ require 'rack/attack/store_proxy/redis_store_proxy'
13
+ require 'rack/attack/store_proxy/redis_cache_store_proxy'
14
+ require 'rack/attack/store_proxy/active_support_redis_store_proxy'
9
15
 
10
16
  require 'rack/attack/railtie' if defined?(::Rails)
11
17
 
@@ -21,18 +27,11 @@ module Rack
21
27
  autoload :Safelist, 'rack/attack/safelist'
22
28
  autoload :Blocklist, 'rack/attack/blocklist'
23
29
  autoload :Track, 'rack/attack/track'
24
- autoload :StoreProxy, 'rack/attack/store_proxy'
25
- autoload :DalliProxy, 'rack/attack/store_proxy/dalli_proxy'
26
- autoload :MemCacheStoreProxy, 'rack/attack/store_proxy/mem_cache_store_proxy'
27
- autoload :RedisProxy, 'rack/attack/store_proxy/redis_proxy'
28
- autoload :RedisStoreProxy, 'rack/attack/store_proxy/redis_store_proxy'
29
- autoload :RedisCacheStoreProxy, 'rack/attack/store_proxy/redis_cache_store_proxy'
30
- autoload :ActiveSupportRedisStoreProxy, 'rack/attack/store_proxy/active_support_redis_store_proxy'
31
30
  autoload :Fail2Ban, 'rack/attack/fail2ban'
32
31
  autoload :Allow2Ban, 'rack/attack/allow2ban'
33
32
 
34
33
  class << self
35
- attr_accessor :enabled, :notifier
34
+ attr_accessor :enabled, :notifier, :throttle_discriminator_normalizer
36
35
  attr_reader :configuration
37
36
 
38
37
  def instrument(request)
@@ -84,6 +83,9 @@ module Rack
84
83
  # Set defaults
85
84
  @enabled = true
86
85
  @notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
86
+ @throttle_discriminator_normalizer = lambda do |discriminator|
87
+ discriminator.to_s.strip.downcase
88
+ end
87
89
  @configuration = Configuration.new
88
90
 
89
91
  attr_reader :configuration
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module Rack
6
+ class Attack
7
+ class BaseProxy < SimpleDelegator
8
+ class << self
9
+ def proxies
10
+ @@proxies ||= []
11
+ end
12
+
13
+ def inherited(klass)
14
+ proxies << klass
15
+ end
16
+
17
+ def lookup(store)
18
+ proxies.find { |proxy| proxy.handle?(store) }
19
+ end
20
+
21
+ def handle?(_store)
22
+ raise NotImplementedError
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -12,8 +12,14 @@ module Rack
12
12
  end
13
13
 
14
14
  attr_reader :store
15
+
15
16
  def store=(store)
16
- @store = StoreProxy.build(store)
17
+ @store =
18
+ if (proxy = BaseProxy.lookup(store))
19
+ proxy.new(store)
20
+ else
21
+ store
22
+ end
17
23
  end
18
24
 
19
25
  def count(unprefixed_key, period)
@@ -4,6 +4,7 @@ module Rack
4
4
  class Attack
5
5
  class Check
6
6
  attr_reader :name, :block, :type
7
+
7
8
  def initialize(name, options = {}, &block)
8
9
  @name = name
9
10
  @block = block
@@ -4,9 +4,7 @@ module Rack
4
4
  class Attack
5
5
  class Railtie < ::Rails::Railtie
6
6
  initializer "rack-attack.middleware" do |app|
7
- if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("5.1")
8
- app.middleware.use(Rack::Attack)
9
- end
7
+ app.middleware.use(Rack::Attack)
10
8
  end
11
9
  end
12
10
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/base_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
7
7
  module StoreProxy
8
- class ActiveSupportRedisStoreProxy < SimpleDelegator
8
+ class ActiveSupportRedisStoreProxy < BaseProxy
9
9
  def self.handle?(store)
10
10
  defined?(::Redis) &&
11
11
  defined?(::ActiveSupport::Cache::RedisStore) &&
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/base_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
7
7
  module StoreProxy
8
- class DalliProxy < SimpleDelegator
8
+ class DalliProxy < BaseProxy
9
9
  def self.handle?(store)
10
10
  return false unless defined?(::Dalli)
11
11
 
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/base_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
7
7
  module StoreProxy
8
- class MemCacheStoreProxy < SimpleDelegator
8
+ class MemCacheStoreProxy < BaseProxy
9
9
  def self.handle?(store)
10
10
  defined?(::Dalli) &&
11
11
  defined?(::ActiveSupport::Cache::MemCacheStore) &&
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/base_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
7
7
  module StoreProxy
8
- class RedisCacheStoreProxy < SimpleDelegator
8
+ class RedisCacheStoreProxy < BaseProxy
9
9
  def self.handle?(store)
10
10
  store.class.name == "ActiveSupport::Cache::RedisCacheStore"
11
11
  end
12
12
 
13
- def increment(name, amount = 1, options = {})
13
+ def increment(name, amount = 1, **options)
14
14
  # RedisCacheStore#increment ignores options[:expires_in].
15
15
  #
16
16
  # So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/base_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
7
7
  module StoreProxy
8
- class RedisProxy < SimpleDelegator
8
+ class RedisProxy < BaseProxy
9
9
  def initialize(*args)
10
10
  if Gem::Version.new(Redis::VERSION) < Gem::Version.new("3")
11
11
  warn 'RackAttack requires Redis gem >= 3.0.0.'
@@ -15,7 +15,7 @@ module Rack
15
15
  end
16
16
 
17
17
  def self.handle?(store)
18
- defined?(::Redis) && store.is_a?(::Redis)
18
+ defined?(::Redis) && store.class == ::Redis
19
19
  end
20
20
 
21
21
  def read(key)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'delegate'
3
+ require 'rack/attack/store_proxy/redis_proxy'
4
4
 
5
5
  module Rack
6
6
  class Attack
@@ -6,6 +6,7 @@ module Rack
6
6
  MANDATORY_OPTIONS = [:limit, :period].freeze
7
7
 
8
8
  attr_reader :name, :limit, :period, :block, :type
9
+
9
10
  def initialize(name, options, &block)
10
11
  @name = name
11
12
  @block = block
@@ -22,8 +23,7 @@ module Rack
22
23
  end
23
24
 
24
25
  def matched_by?(request)
25
- discriminator = block.call(request)
26
-
26
+ discriminator = discriminator_for(request)
27
27
  return false unless discriminator
28
28
 
29
29
  current_period = period_for(request)
@@ -49,6 +49,14 @@ module Rack
49
49
 
50
50
  private
51
51
 
52
+ def discriminator_for(request)
53
+ discriminator = block.call(request)
54
+ if discriminator && Rack::Attack.throttle_discriminator_normalizer
55
+ discriminator = Rack::Attack.throttle_discriminator_normalizer.call(discriminator)
56
+ end
57
+ discriminator
58
+ end
59
+
52
60
  def period_for(request)
53
61
  period.respond_to?(:call) ? period.call(request) : period
54
62
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class Attack
5
- VERSION = '6.3.1'
5
+ VERSION = '6.5.0'
6
6
  end
7
7
  end
@@ -12,24 +12,9 @@ if defined?(Rails)
12
12
  end
13
13
  end
14
14
 
15
- if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("5.1")
16
- it "is used by default" do
17
- @app.initialize!
18
- assert_equal 1, @app.middleware.count(Rack::Attack)
19
- end
20
-
21
- it "is not added when it was explicitly deleted" do
22
- @app.config.middleware.delete(Rack::Attack)
23
- @app.initialize!
24
- refute @app.middleware.include?(Rack::Attack)
25
- end
26
- end
27
-
28
- if Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new("5.1")
29
- it "is not used by default" do
30
- @app.initialize!
31
- assert_equal 0, @app.middleware.count(Rack::Attack)
32
- end
15
+ it "is used by default" do
16
+ @app.initialize!
17
+ assert @app.middleware.include?(Rack::Attack)
33
18
  end
34
19
  end
35
20
  end
@@ -21,6 +21,6 @@ if should_run
21
21
  Rack::Attack.cache.store.clear
22
22
  end
23
23
 
24
- it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.fetch(key) })
24
+ it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.read(key) })
25
25
  end
26
26
  end
@@ -20,6 +20,6 @@ if should_run
20
20
  Rack::Attack.cache.store.clear
21
21
  end
22
22
 
23
- it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.fetch(key) })
23
+ it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.read(key) })
24
24
  end
25
25
  end
@@ -144,3 +144,47 @@ describe 'Rack::Attack.throttle with block retuning nil' do
144
144
  end
145
145
  end
146
146
  end
147
+
148
+ describe 'Rack::Attack.throttle with throttle_discriminator_normalizer' do
149
+ before do
150
+ @period = 60
151
+ @emails = [
152
+ "person@example.com",
153
+ "PERSON@example.com ",
154
+ " person@example.com\r\n ",
155
+ ]
156
+ Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
157
+ Rack::Attack.throttle('logins/email', limit: 4, period: @period) do |req|
158
+ if req.path == '/login' && req.post?
159
+ req.params['email']
160
+ end
161
+ end
162
+ end
163
+
164
+ it 'should not differentiate requests when throttle_discriminator_normalizer is enabled' do
165
+ post_logins
166
+ key = "rack::attack:#{Time.now.to_i / @period}:logins/email:person@example.com"
167
+ _(Rack::Attack.cache.store.read(key)).must_equal 3
168
+ end
169
+
170
+ it 'should differentiate requests when throttle_discriminator_normalizer is disabled' do
171
+ begin
172
+ prev = Rack::Attack.throttle_discriminator_normalizer
173
+ Rack::Attack.throttle_discriminator_normalizer = nil
174
+
175
+ post_logins
176
+ @emails.each do |email|
177
+ key = "rack::attack:#{Time.now.to_i / @period}:logins/email:#{email}"
178
+ _(Rack::Attack.cache.store.read(key)).must_equal 1
179
+ end
180
+ ensure
181
+ Rack::Attack.throttle_discriminator_normalizer = prev
182
+ end
183
+ end
184
+
185
+ def post_logins
186
+ @emails.each do |email|
187
+ post '/login', email: email
188
+ end
189
+ end
190
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-attack
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.1
4
+ version: 6.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Suggs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2021-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -126,14 +126,14 @@ dependencies:
126
126
  requirements:
127
127
  - - '='
128
128
  - !ruby/object:Gem::Version
129
- version: 0.78.0
129
+ version: 0.89.1
130
130
  type: :development
131
131
  prerelease: false
132
132
  version_requirements: !ruby/object:Gem::Requirement
133
133
  requirements:
134
134
  - - '='
135
135
  - !ruby/object:Gem::Version
136
- version: 0.78.0
136
+ version: 0.89.1
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: rubocop-performance
139
139
  requirement: !ruby/object:Gem::Requirement
@@ -185,7 +185,7 @@ dependencies:
185
185
  version: '4.2'
186
186
  - - "<"
187
187
  - !ruby/object:Gem::Version
188
- version: '6.1'
188
+ version: '6.2'
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
@@ -195,7 +195,7 @@ dependencies:
195
195
  version: '4.2'
196
196
  - - "<"
197
197
  - !ruby/object:Gem::Version
198
- version: '6.1'
198
+ version: '6.2'
199
199
  description: A rack middleware for throttling and blocking abusive requests
200
200
  email: aaron@ktheory.com
201
201
  executables: []
@@ -204,9 +204,9 @@ extra_rdoc_files: []
204
204
  files:
205
205
  - README.md
206
206
  - Rakefile
207
- - bin/setup
208
207
  - lib/rack/attack.rb
209
208
  - lib/rack/attack/allow2ban.rb
209
+ - lib/rack/attack/base_proxy.rb
210
210
  - lib/rack/attack/blocklist.rb
211
211
  - lib/rack/attack/cache.rb
212
212
  - lib/rack/attack/check.rb
@@ -216,7 +216,6 @@ files:
216
216
  - lib/rack/attack/railtie.rb
217
217
  - lib/rack/attack/request.rb
218
218
  - lib/rack/attack/safelist.rb
219
- - lib/rack/attack/store_proxy.rb
220
219
  - lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb
221
220
  - lib/rack/attack/store_proxy/dalli_proxy.rb
222
221
  - lib/rack/attack/store_proxy/mem_cache_store_proxy.rb
@@ -268,13 +267,13 @@ files:
268
267
  - spec/rack_attack_track_spec.rb
269
268
  - spec/spec_helper.rb
270
269
  - spec/support/cache_store_helper.rb
271
- homepage: https://github.com/kickstarter/rack-attack
270
+ homepage: https://github.com/rack/rack-attack
272
271
  licenses:
273
272
  - MIT
274
273
  metadata:
275
- bug_tracker_uri: https://github.com/kickstarter/rack-attack/issues
276
- changelog_uri: https://github.com/kickstarter/rack-attack/blob/master/CHANGELOG.md
277
- source_code_uri: https://github.com/kickstarter/rack-attack
274
+ bug_tracker_uri: https://github.com/rack/rack-attack/issues
275
+ changelog_uri: https://github.com/rack/rack-attack/blob/master/CHANGELOG.md
276
+ source_code_uri: https://github.com/rack/rack-attack
278
277
  post_install_message:
279
278
  rdoc_options:
280
279
  - "--charset=UTF-8"
@@ -284,57 +283,57 @@ required_ruby_version: !ruby/object:Gem::Requirement
284
283
  requirements:
285
284
  - - ">="
286
285
  - !ruby/object:Gem::Version
287
- version: '2.3'
286
+ version: '2.4'
288
287
  required_rubygems_version: !ruby/object:Gem::Requirement
289
288
  requirements:
290
289
  - - ">="
291
290
  - !ruby/object:Gem::Version
292
291
  version: '0'
293
292
  requirements: []
294
- rubygems_version: 3.1.3
293
+ rubygems_version: 3.2.8
295
294
  signing_key:
296
295
  specification_version: 4
297
296
  summary: Block & throttle abusive requests
298
297
  test_files:
299
- - spec/integration/offline_spec.rb
300
- - spec/rack_attack_path_normalizer_spec.rb
301
- - spec/acceptance/safelisting_subnet_spec.rb
302
- - spec/acceptance/rails_middleware_spec.rb
303
- - spec/acceptance/track_throttle_spec.rb
304
- - spec/acceptance/cache_store_config_for_fail2ban_spec.rb
305
- - spec/acceptance/cache_store_config_with_rails_spec.rb
306
- - spec/acceptance/cache_store_config_for_allow2ban_spec.rb
307
- - spec/acceptance/safelisting_ip_spec.rb
308
- - spec/acceptance/track_spec.rb
309
- - spec/acceptance/blocking_subnet_spec.rb
310
- - spec/acceptance/blocking_ip_spec.rb
311
298
  - spec/acceptance/allow2ban_spec.rb
312
- - spec/acceptance/throttling_spec.rb
299
+ - spec/acceptance/blocking_ip_spec.rb
313
300
  - spec/acceptance/blocking_spec.rb
301
+ - spec/acceptance/blocking_subnet_spec.rb
302
+ - spec/acceptance/cache_store_config_for_allow2ban_spec.rb
303
+ - spec/acceptance/cache_store_config_for_fail2ban_spec.rb
304
+ - spec/acceptance/cache_store_config_for_throttle_spec.rb
305
+ - spec/acceptance/cache_store_config_with_rails_spec.rb
306
+ - spec/acceptance/customizing_blocked_response_spec.rb
314
307
  - spec/acceptance/customizing_throttled_response_spec.rb
315
308
  - spec/acceptance/extending_request_object_spec.rb
316
- - spec/acceptance/safelisting_spec.rb
317
- - spec/acceptance/cache_store_config_for_throttle_spec.rb
318
309
  - spec/acceptance/fail2ban_spec.rb
310
+ - spec/acceptance/rails_middleware_spec.rb
311
+ - spec/acceptance/safelisting_ip_spec.rb
312
+ - spec/acceptance/safelisting_spec.rb
313
+ - spec/acceptance/safelisting_subnet_spec.rb
314
+ - spec/acceptance/stores/active_support_dalli_store_spec.rb
319
315
  - spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb
320
- - spec/acceptance/stores/active_support_redis_cache_store_spec.rb
321
- - spec/acceptance/stores/active_support_memory_store_spec.rb
322
- - spec/acceptance/stores/active_support_redis_store_spec.rb
323
316
  - spec/acceptance/stores/active_support_mem_cache_store_spec.rb
317
+ - spec/acceptance/stores/active_support_memory_store_spec.rb
324
318
  - spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb
319
+ - spec/acceptance/stores/active_support_redis_cache_store_spec.rb
320
+ - spec/acceptance/stores/active_support_redis_store_spec.rb
325
321
  - spec/acceptance/stores/connection_pool_dalli_client_spec.rb
326
- - spec/acceptance/stores/active_support_dalli_store_spec.rb
327
- - spec/acceptance/stores/redis_store_spec.rb
328
322
  - spec/acceptance/stores/dalli_client_spec.rb
329
323
  - spec/acceptance/stores/redis_spec.rb
330
- - spec/acceptance/customizing_blocked_response_spec.rb
331
- - spec/spec_helper.rb
324
+ - spec/acceptance/stores/redis_store_spec.rb
325
+ - spec/acceptance/throttling_spec.rb
326
+ - spec/acceptance/track_spec.rb
327
+ - spec/acceptance/track_throttle_spec.rb
332
328
  - spec/allow2ban_spec.rb
333
- - spec/rack_attack_instrumentation_spec.rb
329
+ - spec/fail2ban_spec.rb
330
+ - spec/integration/offline_spec.rb
334
331
  - spec/rack_attack_dalli_proxy_spec.rb
332
+ - spec/rack_attack_instrumentation_spec.rb
333
+ - spec/rack_attack_path_normalizer_spec.rb
334
+ - spec/rack_attack_request_spec.rb
335
335
  - spec/rack_attack_spec.rb
336
336
  - spec/rack_attack_throttle_spec.rb
337
- - spec/rack_attack_request_spec.rb
338
- - spec/fail2ban_spec.rb
339
337
  - spec/rack_attack_track_spec.rb
338
+ - spec/spec_helper.rb
340
339
  - spec/support/cache_store_helper.rb
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rack
4
- class Attack
5
- module StoreProxy
6
- PROXIES = [
7
- DalliProxy,
8
- MemCacheStoreProxy,
9
- RedisStoreProxy,
10
- RedisProxy,
11
- RedisCacheStoreProxy,
12
- ActiveSupportRedisStoreProxy
13
- ].freeze
14
-
15
- def self.build(store)
16
- klass = PROXIES.find { |proxy| proxy.handle?(store) }
17
- klass ? klass.new(store) : store
18
- end
19
- end
20
- end
21
- end