rack-attack 5.4.1 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -27
  3. data/Rakefile +3 -1
  4. data/lib/rack/attack.rb +138 -149
  5. data/lib/rack/attack/allow2ban.rb +2 -0
  6. data/lib/rack/attack/blocklist.rb +3 -1
  7. data/lib/rack/attack/cache.rb +9 -4
  8. data/lib/rack/attack/check.rb +5 -2
  9. data/lib/rack/attack/fail2ban.rb +2 -0
  10. data/lib/rack/attack/path_normalizer.rb +22 -18
  11. data/lib/rack/attack/railtie.rb +13 -0
  12. data/lib/rack/attack/request.rb +2 -0
  13. data/lib/rack/attack/safelist.rb +3 -1
  14. data/lib/rack/attack/store_proxy.rb +12 -14
  15. data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +39 -0
  16. data/lib/rack/attack/store_proxy/dalli_proxy.rb +27 -13
  17. data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +3 -1
  18. data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +23 -9
  19. data/lib/rack/attack/store_proxy/redis_proxy.rb +16 -10
  20. data/lib/rack/attack/store_proxy/redis_store_proxy.rb +5 -5
  21. data/lib/rack/attack/throttle.rb +12 -8
  22. data/lib/rack/attack/track.rb +9 -6
  23. data/lib/rack/attack/version.rb +3 -1
  24. data/spec/acceptance/allow2ban_spec.rb +2 -0
  25. data/spec/acceptance/blocking_ip_spec.rb +4 -2
  26. data/spec/acceptance/blocking_spec.rb +45 -3
  27. data/spec/acceptance/blocking_subnet_spec.rb +4 -2
  28. data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +50 -39
  29. data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +38 -29
  30. data/spec/acceptance/cache_store_config_for_throttle_spec.rb +2 -0
  31. data/spec/acceptance/cache_store_config_with_rails_spec.rb +2 -0
  32. data/spec/acceptance/customizing_blocked_response_spec.rb +2 -0
  33. data/spec/acceptance/customizing_throttled_response_spec.rb +2 -0
  34. data/spec/acceptance/extending_request_object_spec.rb +2 -0
  35. data/spec/acceptance/fail2ban_spec.rb +2 -0
  36. data/spec/acceptance/rails_middleware_spec.rb +35 -0
  37. data/spec/acceptance/safelisting_ip_spec.rb +4 -2
  38. data/spec/acceptance/safelisting_spec.rb +57 -3
  39. data/spec/acceptance/safelisting_subnet_spec.rb +4 -2
  40. data/spec/acceptance/stores/active_support_dalli_store_spec.rb +2 -0
  41. data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +1 -3
  42. data/spec/acceptance/stores/active_support_mem_cache_store_spec.rb +2 -0
  43. data/spec/acceptance/stores/active_support_memory_store_spec.rb +2 -0
  44. data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +9 -1
  45. data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +8 -1
  46. data/spec/acceptance/stores/active_support_redis_store_spec.rb +3 -1
  47. data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +5 -3
  48. data/spec/acceptance/stores/dalli_client_spec.rb +2 -0
  49. data/spec/acceptance/stores/redis_store_spec.rb +2 -0
  50. data/spec/acceptance/throttling_spec.rb +7 -5
  51. data/spec/acceptance/track_spec.rb +5 -3
  52. data/spec/acceptance/track_throttle_spec.rb +5 -3
  53. data/spec/allow2ban_spec.rb +20 -15
  54. data/spec/fail2ban_spec.rb +20 -17
  55. data/spec/integration/offline_spec.rb +3 -1
  56. data/spec/rack_attack_dalli_proxy_spec.rb +2 -0
  57. data/spec/rack_attack_instrumentation_spec.rb +42 -0
  58. data/spec/rack_attack_path_normalizer_spec.rb +4 -2
  59. data/spec/rack_attack_request_spec.rb +2 -0
  60. data/spec/rack_attack_spec.rb +38 -34
  61. data/spec/rack_attack_throttle_spec.rb +50 -19
  62. data/spec/rack_attack_track_spec.rb +12 -7
  63. data/spec/spec_helper.rb +12 -8
  64. data/spec/support/cache_store_helper.rb +2 -0
  65. metadata +44 -28
  66. data/lib/rack/attack/store_proxy/mem_cache_proxy.rb +0 -50
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'spec_helper'
2
4
 
3
5
  describe 'Rack::Attack.track' do
@@ -23,8 +25,9 @@ describe 'Rack::Attack.track' do
23
25
 
24
26
  it "should tag the env" do
25
27
  get '/'
26
- last_request.env['rack.attack.matched'].must_equal 'everything'
27
- last_request.env['rack.attack.match_type'].must_equal :track
28
+
29
+ _(last_request.env['rack.attack.matched']).must_equal 'everything'
30
+ _(last_request.env['rack.attack.match_type']).must_equal :track
28
31
  end
29
32
 
30
33
  describe "with a notification subscriber and two tracks" do
@@ -33,7 +36,7 @@ describe 'Rack::Attack.track' do
33
36
  # A second track
34
37
  Rack::Attack.track("homepage") { |req| req.path == "/" }
35
38
 
36
- ActiveSupport::Notifications.subscribe("rack.attack") do |*_args|
39
+ ActiveSupport::Notifications.subscribe("track.rack_attack") do |*_args|
37
40
  Counter.incr
38
41
  end
39
42
 
@@ -41,21 +44,23 @@ describe 'Rack::Attack.track' do
41
44
  end
42
45
 
43
46
  it "should notify twice" do
44
- Counter.check.must_equal 2
47
+ _(Counter.check).must_equal 2
45
48
  end
46
49
  end
47
50
 
48
51
  describe "without limit and period options" do
49
52
  it "should assign the track filter to a Check instance" do
50
53
  track = Rack::Attack.track("homepage") { |req| req.path == "/" }
51
- track.filter.class.must_equal Rack::Attack::Check
54
+
55
+ _(track.filter.class).must_equal Rack::Attack::Check
52
56
  end
53
57
  end
54
58
 
55
59
  describe "with limit and period options" do
56
60
  it "should assign the track filter to a Throttle instance" do
57
- track = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/" }
58
- track.filter.class.must_equal Rack::Attack::Throttle
61
+ track = Rack::Attack.track("homepage", limit: 10, period: 10) { |req| req.path == "/" }
62
+
63
+ _(track.filter.class).must_equal Rack::Attack::Throttle
59
64
  end
60
65
  end
61
66
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/setup"
2
4
 
3
5
  require "minitest/autorun"
4
6
  require "minitest/pride"
5
7
  require "rack/test"
6
- require 'active_support'
7
- require 'action_dispatch'
8
+ require "rails"
8
9
 
9
10
  require "rack/attack"
10
11
 
@@ -13,10 +14,9 @@ if RUBY_ENGINE == "ruby"
13
14
  end
14
15
 
15
16
  def safe_require(name)
16
- begin
17
- require name
18
- rescue LoadError
19
- end
17
+ require name
18
+ rescue LoadError
19
+ nil
20
20
  end
21
21
 
22
22
  safe_require "connection_pool"
@@ -29,6 +29,7 @@ class MiniTest::Spec
29
29
  include Rack::Test::Methods
30
30
 
31
31
  before do
32
+ Rails.cache = nil
32
33
  @_original_throttled_response = Rack::Attack.throttled_response
33
34
  @_original_blocklisted_response = Rack::Attack.blocklisted_response
34
35
  end
@@ -45,6 +46,8 @@ class MiniTest::Spec
45
46
  Rack::Builder.new do
46
47
  # Use Rack::Lint to test that rack-attack is complying with the rack spec
47
48
  use Rack::Lint
49
+ # Intentionally added twice to test idempotence property
50
+ use Rack::Attack
48
51
  use Rack::Attack
49
52
  use Rack::Lint
50
53
 
@@ -55,8 +58,9 @@ class MiniTest::Spec
55
58
  def self.it_allows_ok_requests
56
59
  it "must allow ok requests" do
57
60
  get '/', {}, 'REMOTE_ADDR' => '127.0.0.1'
58
- last_response.status.must_equal 200
59
- last_response.body.must_equal 'Hello World'
61
+
62
+ _(last_response.status).must_equal 200
63
+ _(last_response.body).must_equal 'Hello World'
60
64
  end
61
65
  end
62
66
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Minitest::Spec
2
4
  def self.it_works_for_cache_backed_features(options)
3
5
  fetch_from_store = options.fetch(:fetch_from_store)
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: 5.4.1
4
+ version: 6.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Suggs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-29 00:00:00.000000000 Z
11
+ date: 2019-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -48,16 +48,22 @@ dependencies:
48
48
  name: bundler
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '1.17'
54
+ - - "<"
52
55
  - !ruby/object:Gem::Version
53
- version: '1.16'
56
+ version: '3.0'
54
57
  type: :development
55
58
  prerelease: false
56
59
  version_requirements: !ruby/object:Gem::Requirement
57
60
  requirements:
58
- - - "~>"
61
+ - - ">="
59
62
  - !ruby/object:Gem::Version
60
- version: '1.16'
63
+ version: '1.17'
64
+ - - "<"
65
+ - !ruby/object:Gem::Version
66
+ version: '3.0'
61
67
  - !ruby/object:Gem::Dependency
62
68
  name: minitest
63
69
  requirement: !ruby/object:Gem::Requirement
@@ -106,84 +112,90 @@ dependencies:
106
112
  requirements:
107
113
  - - "~>"
108
114
  - !ruby/object:Gem::Version
109
- version: '12.3'
115
+ version: '13.0'
110
116
  type: :development
111
117
  prerelease: false
112
118
  version_requirements: !ruby/object:Gem::Requirement
113
119
  requirements:
114
120
  - - "~>"
115
121
  - !ruby/object:Gem::Version
116
- version: '12.3'
122
+ version: '13.0'
117
123
  - !ruby/object:Gem::Dependency
118
124
  name: rubocop
119
125
  requirement: !ruby/object:Gem::Requirement
120
126
  requirements:
121
127
  - - '='
122
128
  - !ruby/object:Gem::Version
123
- version: 0.58.2
129
+ version: 0.75.0
124
130
  type: :development
125
131
  prerelease: false
126
132
  version_requirements: !ruby/object:Gem::Requirement
127
133
  requirements:
128
134
  - - '='
129
135
  - !ruby/object:Gem::Version
130
- version: 0.58.2
136
+ version: 0.75.0
131
137
  - !ruby/object:Gem::Dependency
132
- name: timecop
138
+ name: rubocop-performance
133
139
  requirement: !ruby/object:Gem::Requirement
134
140
  requirements:
135
141
  - - "~>"
136
142
  - !ruby/object:Gem::Version
137
- version: 0.9.1
143
+ version: 1.5.0
138
144
  type: :development
139
145
  prerelease: false
140
146
  version_requirements: !ruby/object:Gem::Requirement
141
147
  requirements:
142
148
  - - "~>"
143
149
  - !ruby/object:Gem::Version
144
- version: 0.9.1
150
+ version: 1.5.0
145
151
  - !ruby/object:Gem::Dependency
146
- name: byebug
152
+ name: timecop
147
153
  requirement: !ruby/object:Gem::Requirement
148
154
  requirements:
149
155
  - - "~>"
150
156
  - !ruby/object:Gem::Version
151
- version: '10.0'
157
+ version: 0.9.1
152
158
  type: :development
153
159
  prerelease: false
154
160
  version_requirements: !ruby/object:Gem::Requirement
155
161
  requirements:
156
162
  - - "~>"
157
163
  - !ruby/object:Gem::Version
158
- version: '10.0'
164
+ version: 0.9.1
159
165
  - !ruby/object:Gem::Dependency
160
- name: actionpack
166
+ name: byebug
161
167
  requirement: !ruby/object:Gem::Requirement
162
168
  requirements:
163
169
  - - "~>"
164
170
  - !ruby/object:Gem::Version
165
- version: '5.2'
171
+ version: '11.0'
166
172
  type: :development
167
173
  prerelease: false
168
174
  version_requirements: !ruby/object:Gem::Requirement
169
175
  requirements:
170
176
  - - "~>"
171
177
  - !ruby/object:Gem::Version
172
- version: '5.2'
178
+ version: '11.0'
173
179
  - !ruby/object:Gem::Dependency
174
- name: activesupport
180
+ name: railties
175
181
  requirement: !ruby/object:Gem::Requirement
176
182
  requirements:
177
- - - "~>"
183
+ - - ">="
178
184
  - !ruby/object:Gem::Version
179
- version: '5.2'
185
+ version: '4.2'
186
+ - - "<"
187
+ - !ruby/object:Gem::Version
188
+ version: '6.1'
180
189
  type: :development
181
190
  prerelease: false
182
191
  version_requirements: !ruby/object:Gem::Requirement
183
192
  requirements:
184
- - - "~>"
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '4.2'
196
+ - - "<"
185
197
  - !ruby/object:Gem::Version
186
- version: '5.2'
198
+ version: '6.1'
187
199
  description: A rack middleware for throttling and blocking abusive requests
188
200
  email: aaron@ktheory.com
189
201
  executables: []
@@ -200,11 +212,12 @@ files:
200
212
  - lib/rack/attack/check.rb
201
213
  - lib/rack/attack/fail2ban.rb
202
214
  - lib/rack/attack/path_normalizer.rb
215
+ - lib/rack/attack/railtie.rb
203
216
  - lib/rack/attack/request.rb
204
217
  - lib/rack/attack/safelist.rb
205
218
  - lib/rack/attack/store_proxy.rb
219
+ - lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb
206
220
  - lib/rack/attack/store_proxy/dalli_proxy.rb
207
- - lib/rack/attack/store_proxy/mem_cache_proxy.rb
208
221
  - lib/rack/attack/store_proxy/mem_cache_store_proxy.rb
209
222
  - lib/rack/attack/store_proxy/redis_cache_store_proxy.rb
210
223
  - lib/rack/attack/store_proxy/redis_proxy.rb
@@ -224,6 +237,7 @@ files:
224
237
  - spec/acceptance/customizing_throttled_response_spec.rb
225
238
  - spec/acceptance/extending_request_object_spec.rb
226
239
  - spec/acceptance/fail2ban_spec.rb
240
+ - spec/acceptance/rails_middleware_spec.rb
227
241
  - spec/acceptance/safelisting_ip_spec.rb
228
242
  - spec/acceptance/safelisting_spec.rb
229
243
  - spec/acceptance/safelisting_subnet_spec.rb
@@ -245,6 +259,7 @@ files:
245
259
  - spec/fail2ban_spec.rb
246
260
  - spec/integration/offline_spec.rb
247
261
  - spec/rack_attack_dalli_proxy_spec.rb
262
+ - spec/rack_attack_instrumentation_spec.rb
248
263
  - spec/rack_attack_path_normalizer_spec.rb
249
264
  - spec/rack_attack_request_spec.rb
250
265
  - spec/rack_attack_spec.rb
@@ -268,15 +283,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
268
283
  requirements:
269
284
  - - ">="
270
285
  - !ruby/object:Gem::Version
271
- version: '2.2'
286
+ version: '2.3'
272
287
  required_rubygems_version: !ruby/object:Gem::Requirement
273
288
  requirements:
274
289
  - - ">="
275
290
  - !ruby/object:Gem::Version
276
291
  version: '0'
277
292
  requirements: []
278
- rubyforge_project:
279
- rubygems_version: 2.7.7
293
+ rubygems_version: 3.0.6
280
294
  signing_key:
281
295
  specification_version: 4
282
296
  summary: Block & throttle abusive requests
@@ -284,6 +298,7 @@ test_files:
284
298
  - spec/integration/offline_spec.rb
285
299
  - spec/rack_attack_path_normalizer_spec.rb
286
300
  - spec/acceptance/safelisting_subnet_spec.rb
301
+ - spec/acceptance/rails_middleware_spec.rb
287
302
  - spec/acceptance/track_throttle_spec.rb
288
303
  - spec/acceptance/cache_store_config_for_fail2ban_spec.rb
289
304
  - spec/acceptance/cache_store_config_with_rails_spec.rb
@@ -314,6 +329,7 @@ test_files:
314
329
  - spec/acceptance/customizing_blocked_response_spec.rb
315
330
  - spec/spec_helper.rb
316
331
  - spec/allow2ban_spec.rb
332
+ - spec/rack_attack_instrumentation_spec.rb
317
333
  - spec/rack_attack_dalli_proxy_spec.rb
318
334
  - spec/rack_attack_spec.rb
319
335
  - spec/rack_attack_throttle_spec.rb
@@ -1,50 +0,0 @@
1
- module Rack
2
- class Attack
3
- module StoreProxy
4
- class MemCacheProxy < SimpleDelegator
5
- def self.handle?(store)
6
- defined?(::MemCache) && store.is_a?(::MemCache)
7
- end
8
-
9
- def initialize(store)
10
- super(store)
11
- stub_with_if_missing
12
- end
13
-
14
- def read(key)
15
- # Second argument: reading raw value
16
- get(key, true)
17
- rescue MemCache::MemCacheError
18
- end
19
-
20
- def write(key, value, options = {})
21
- # Third argument: writing raw value
22
- set(key, value, options.fetch(:expires_in, 0), true)
23
- rescue MemCache::MemCacheError
24
- end
25
-
26
- def increment(key, amount, _options = {})
27
- incr(key, amount)
28
- rescue MemCache::MemCacheError
29
- end
30
-
31
- def delete(key, _options = {})
32
- with do |client|
33
- client.delete(key)
34
- end
35
- rescue MemCache::MemCacheError
36
- end
37
-
38
- private
39
-
40
- def stub_with_if_missing
41
- unless __getobj__.respond_to?(:with)
42
- class << self
43
- def with; yield __getobj__; end
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end