rack-attack 5.4.0 → 6.2.0

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -27
  3. data/Rakefile +3 -1
  4. data/bin/setup +8 -0
  5. data/lib/rack/attack.rb +137 -148
  6. data/lib/rack/attack/allow2ban.rb +2 -0
  7. data/lib/rack/attack/blocklist.rb +3 -1
  8. data/lib/rack/attack/cache.rb +9 -4
  9. data/lib/rack/attack/check.rb +5 -2
  10. data/lib/rack/attack/fail2ban.rb +2 -0
  11. data/lib/rack/attack/path_normalizer.rb +22 -18
  12. data/lib/rack/attack/railtie.rb +21 -0
  13. data/lib/rack/attack/request.rb +2 -0
  14. data/lib/rack/attack/safelist.rb +3 -1
  15. data/lib/rack/attack/store_proxy.rb +12 -24
  16. data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +39 -0
  17. data/lib/rack/attack/store_proxy/dalli_proxy.rb +27 -13
  18. data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +21 -0
  19. data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +23 -9
  20. data/lib/rack/attack/store_proxy/redis_proxy.rb +16 -10
  21. data/lib/rack/attack/store_proxy/redis_store_proxy.rb +5 -5
  22. data/lib/rack/attack/throttle.rb +12 -8
  23. data/lib/rack/attack/track.rb +9 -6
  24. data/lib/rack/attack/version.rb +3 -1
  25. data/spec/acceptance/allow2ban_spec.rb +2 -0
  26. data/spec/acceptance/blocking_ip_spec.rb +4 -2
  27. data/spec/acceptance/blocking_spec.rb +45 -3
  28. data/spec/acceptance/blocking_subnet_spec.rb +4 -2
  29. data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +50 -39
  30. data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +38 -29
  31. data/spec/acceptance/cache_store_config_for_throttle_spec.rb +2 -0
  32. data/spec/acceptance/cache_store_config_with_rails_spec.rb +2 -0
  33. data/spec/acceptance/customizing_blocked_response_spec.rb +2 -0
  34. data/spec/acceptance/customizing_throttled_response_spec.rb +2 -0
  35. data/spec/acceptance/extending_request_object_spec.rb +2 -0
  36. data/spec/acceptance/fail2ban_spec.rb +2 -0
  37. data/spec/acceptance/rails_middleware_spec.rb +41 -0
  38. data/spec/acceptance/safelisting_ip_spec.rb +4 -2
  39. data/spec/acceptance/safelisting_spec.rb +57 -3
  40. data/spec/acceptance/safelisting_subnet_spec.rb +4 -2
  41. data/spec/acceptance/stores/active_support_dalli_store_spec.rb +3 -23
  42. data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +20 -0
  43. data/spec/acceptance/stores/active_support_mem_cache_store_spec.rb +4 -24
  44. data/spec/acceptance/stores/active_support_memory_store_spec.rb +3 -23
  45. data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +10 -24
  46. data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +9 -25
  47. data/spec/acceptance/stores/active_support_redis_store_spec.rb +4 -24
  48. data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +5 -23
  49. data/spec/acceptance/stores/dalli_client_spec.rb +3 -23
  50. data/spec/acceptance/stores/redis_spec.rb +1 -23
  51. data/spec/acceptance/stores/redis_store_spec.rb +3 -23
  52. data/spec/acceptance/throttling_spec.rb +7 -5
  53. data/spec/acceptance/track_spec.rb +5 -3
  54. data/spec/acceptance/track_throttle_spec.rb +5 -3
  55. data/spec/allow2ban_spec.rb +20 -15
  56. data/spec/fail2ban_spec.rb +20 -17
  57. data/spec/integration/offline_spec.rb +3 -1
  58. data/spec/rack_attack_dalli_proxy_spec.rb +2 -0
  59. data/spec/rack_attack_instrumentation_spec.rb +42 -0
  60. data/spec/rack_attack_path_normalizer_spec.rb +4 -2
  61. data/spec/rack_attack_request_spec.rb +2 -0
  62. data/spec/rack_attack_spec.rb +38 -34
  63. data/spec/rack_attack_throttle_spec.rb +50 -19
  64. data/spec/rack_attack_track_spec.rb +12 -7
  65. data/spec/spec_helper.rb +10 -8
  66. data/spec/support/cache_store_helper.rb +27 -1
  67. metadata +48 -28
  68. data/lib/rack/attack/store_proxy/mem_cache_proxy.rb +0 -50
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Minitest::Spec
2
- def self.it_works_for_cache_backed_features
4
+ def self.it_works_for_cache_backed_features(options)
5
+ fetch_from_store = options.fetch(:fetch_from_store)
6
+
3
7
  it "works for throttle" do
4
8
  Rack::Attack.throttle("by ip", limit: 1, period: 60) do |request|
5
9
  request.ip
@@ -54,5 +58,27 @@ class Minitest::Spec
54
58
  get "/"
55
59
  assert_equal 403, last_response.status
56
60
  end
61
+
62
+ it "doesn't leak keys" do
63
+ Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
64
+ request.ip
65
+ end
66
+
67
+ key = nil
68
+
69
+ # Freeze time during these statement to be sure that the key used by rack attack is the same
70
+ # we pre-calculate in local variable `key`
71
+ Timecop.freeze do
72
+ key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
73
+
74
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
75
+ end
76
+
77
+ assert fetch_from_store.call(key)
78
+
79
+ sleep 2.1
80
+
81
+ assert_nil fetch_from_store.call(key)
82
+ end
57
83
  end
58
84
  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: 5.4.0
4
+ version: 6.2.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: 2018-07-02 00:00:00.000000000 Z
11
+ date: 2019-10-12 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.57.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.57.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: []
@@ -192,6 +204,7 @@ extra_rdoc_files: []
192
204
  files:
193
205
  - README.md
194
206
  - Rakefile
207
+ - bin/setup
195
208
  - lib/rack/attack.rb
196
209
  - lib/rack/attack/allow2ban.rb
197
210
  - lib/rack/attack/blocklist.rb
@@ -199,11 +212,13 @@ files:
199
212
  - lib/rack/attack/check.rb
200
213
  - lib/rack/attack/fail2ban.rb
201
214
  - lib/rack/attack/path_normalizer.rb
215
+ - lib/rack/attack/railtie.rb
202
216
  - lib/rack/attack/request.rb
203
217
  - lib/rack/attack/safelist.rb
204
218
  - lib/rack/attack/store_proxy.rb
219
+ - lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb
205
220
  - lib/rack/attack/store_proxy/dalli_proxy.rb
206
- - lib/rack/attack/store_proxy/mem_cache_proxy.rb
221
+ - lib/rack/attack/store_proxy/mem_cache_store_proxy.rb
207
222
  - lib/rack/attack/store_proxy/redis_cache_store_proxy.rb
208
223
  - lib/rack/attack/store_proxy/redis_proxy.rb
209
224
  - lib/rack/attack/store_proxy/redis_store_proxy.rb
@@ -222,10 +237,12 @@ files:
222
237
  - spec/acceptance/customizing_throttled_response_spec.rb
223
238
  - spec/acceptance/extending_request_object_spec.rb
224
239
  - spec/acceptance/fail2ban_spec.rb
240
+ - spec/acceptance/rails_middleware_spec.rb
225
241
  - spec/acceptance/safelisting_ip_spec.rb
226
242
  - spec/acceptance/safelisting_spec.rb
227
243
  - spec/acceptance/safelisting_subnet_spec.rb
228
244
  - spec/acceptance/stores/active_support_dalli_store_spec.rb
245
+ - spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb
229
246
  - spec/acceptance/stores/active_support_mem_cache_store_spec.rb
230
247
  - spec/acceptance/stores/active_support_memory_store_spec.rb
231
248
  - spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb
@@ -242,6 +259,7 @@ files:
242
259
  - spec/fail2ban_spec.rb
243
260
  - spec/integration/offline_spec.rb
244
261
  - spec/rack_attack_dalli_proxy_spec.rb
262
+ - spec/rack_attack_instrumentation_spec.rb
245
263
  - spec/rack_attack_path_normalizer_spec.rb
246
264
  - spec/rack_attack_request_spec.rb
247
265
  - spec/rack_attack_spec.rb
@@ -265,15 +283,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
265
283
  requirements:
266
284
  - - ">="
267
285
  - !ruby/object:Gem::Version
268
- version: '2.2'
286
+ version: '2.3'
269
287
  required_rubygems_version: !ruby/object:Gem::Requirement
270
288
  requirements:
271
289
  - - ">="
272
290
  - !ruby/object:Gem::Version
273
291
  version: '0'
274
292
  requirements: []
275
- rubyforge_project:
276
- rubygems_version: 2.7.7
293
+ rubygems_version: 3.0.6
277
294
  signing_key:
278
295
  specification_version: 4
279
296
  summary: Block & throttle abusive requests
@@ -281,6 +298,7 @@ test_files:
281
298
  - spec/integration/offline_spec.rb
282
299
  - spec/rack_attack_path_normalizer_spec.rb
283
300
  - spec/acceptance/safelisting_subnet_spec.rb
301
+ - spec/acceptance/rails_middleware_spec.rb
284
302
  - spec/acceptance/track_throttle_spec.rb
285
303
  - spec/acceptance/cache_store_config_for_fail2ban_spec.rb
286
304
  - spec/acceptance/cache_store_config_with_rails_spec.rb
@@ -297,6 +315,7 @@ test_files:
297
315
  - spec/acceptance/safelisting_spec.rb
298
316
  - spec/acceptance/cache_store_config_for_throttle_spec.rb
299
317
  - spec/acceptance/fail2ban_spec.rb
318
+ - spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb
300
319
  - spec/acceptance/stores/active_support_redis_cache_store_spec.rb
301
320
  - spec/acceptance/stores/active_support_memory_store_spec.rb
302
321
  - spec/acceptance/stores/active_support_redis_store_spec.rb
@@ -310,6 +329,7 @@ test_files:
310
329
  - spec/acceptance/customizing_blocked_response_spec.rb
311
330
  - spec/spec_helper.rb
312
331
  - spec/allow2ban_spec.rb
332
+ - spec/rack_attack_instrumentation_spec.rb
313
333
  - spec/rack_attack_dalli_proxy_spec.rb
314
334
  - spec/rack_attack_spec.rb
315
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