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.
- checksums.yaml +4 -4
- data/README.md +78 -27
- data/Rakefile +3 -1
- data/bin/setup +8 -0
- data/lib/rack/attack.rb +137 -148
- data/lib/rack/attack/allow2ban.rb +2 -0
- data/lib/rack/attack/blocklist.rb +3 -1
- data/lib/rack/attack/cache.rb +9 -4
- data/lib/rack/attack/check.rb +5 -2
- data/lib/rack/attack/fail2ban.rb +2 -0
- data/lib/rack/attack/path_normalizer.rb +22 -18
- data/lib/rack/attack/railtie.rb +21 -0
- data/lib/rack/attack/request.rb +2 -0
- data/lib/rack/attack/safelist.rb +3 -1
- data/lib/rack/attack/store_proxy.rb +12 -24
- data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +39 -0
- data/lib/rack/attack/store_proxy/dalli_proxy.rb +27 -13
- data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +21 -0
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +23 -9
- data/lib/rack/attack/store_proxy/redis_proxy.rb +16 -10
- data/lib/rack/attack/store_proxy/redis_store_proxy.rb +5 -5
- data/lib/rack/attack/throttle.rb +12 -8
- data/lib/rack/attack/track.rb +9 -6
- data/lib/rack/attack/version.rb +3 -1
- data/spec/acceptance/allow2ban_spec.rb +2 -0
- data/spec/acceptance/blocking_ip_spec.rb +4 -2
- data/spec/acceptance/blocking_spec.rb +45 -3
- data/spec/acceptance/blocking_subnet_spec.rb +4 -2
- data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +50 -39
- data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +38 -29
- data/spec/acceptance/cache_store_config_for_throttle_spec.rb +2 -0
- data/spec/acceptance/cache_store_config_with_rails_spec.rb +2 -0
- data/spec/acceptance/customizing_blocked_response_spec.rb +2 -0
- data/spec/acceptance/customizing_throttled_response_spec.rb +2 -0
- data/spec/acceptance/extending_request_object_spec.rb +2 -0
- data/spec/acceptance/fail2ban_spec.rb +2 -0
- data/spec/acceptance/rails_middleware_spec.rb +41 -0
- data/spec/acceptance/safelisting_ip_spec.rb +4 -2
- data/spec/acceptance/safelisting_spec.rb +57 -3
- data/spec/acceptance/safelisting_subnet_spec.rb +4 -2
- data/spec/acceptance/stores/active_support_dalli_store_spec.rb +3 -23
- data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +20 -0
- data/spec/acceptance/stores/active_support_mem_cache_store_spec.rb +4 -24
- data/spec/acceptance/stores/active_support_memory_store_spec.rb +3 -23
- data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +10 -24
- data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +9 -25
- data/spec/acceptance/stores/active_support_redis_store_spec.rb +4 -24
- data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +5 -23
- data/spec/acceptance/stores/dalli_client_spec.rb +3 -23
- data/spec/acceptance/stores/redis_spec.rb +1 -23
- data/spec/acceptance/stores/redis_store_spec.rb +3 -23
- data/spec/acceptance/throttling_spec.rb +7 -5
- data/spec/acceptance/track_spec.rb +5 -3
- data/spec/acceptance/track_throttle_spec.rb +5 -3
- data/spec/allow2ban_spec.rb +20 -15
- data/spec/fail2ban_spec.rb +20 -17
- data/spec/integration/offline_spec.rb +3 -1
- data/spec/rack_attack_dalli_proxy_spec.rb +2 -0
- data/spec/rack_attack_instrumentation_spec.rb +42 -0
- data/spec/rack_attack_path_normalizer_spec.rb +4 -2
- data/spec/rack_attack_request_spec.rb +2 -0
- data/spec/rack_attack_spec.rb +38 -34
- data/spec/rack_attack_throttle_spec.rb +50 -19
- data/spec/rack_attack_track_spec.rb +12 -7
- data/spec/spec_helper.rb +10 -8
- data/spec/support/cache_store_helper.rb +27 -1
- metadata +48 -28
- 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:
|
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:
|
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: '
|
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.
|
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: '
|
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: '
|
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.
|
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.
|
136
|
+
version: 0.75.0
|
131
137
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
138
|
+
name: rubocop-performance
|
133
139
|
requirement: !ruby/object:Gem::Requirement
|
134
140
|
requirements:
|
135
141
|
- - "~>"
|
136
142
|
- !ruby/object:Gem::Version
|
137
|
-
version:
|
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:
|
150
|
+
version: 1.5.0
|
145
151
|
- !ruby/object:Gem::Dependency
|
146
|
-
name:
|
152
|
+
name: timecop
|
147
153
|
requirement: !ruby/object:Gem::Requirement
|
148
154
|
requirements:
|
149
155
|
- - "~>"
|
150
156
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
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:
|
164
|
+
version: 0.9.1
|
159
165
|
- !ruby/object:Gem::Dependency
|
160
|
-
name:
|
166
|
+
name: byebug
|
161
167
|
requirement: !ruby/object:Gem::Requirement
|
162
168
|
requirements:
|
163
169
|
- - "~>"
|
164
170
|
- !ruby/object:Gem::Version
|
165
|
-
version: '
|
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: '
|
178
|
+
version: '11.0'
|
173
179
|
- !ruby/object:Gem::Dependency
|
174
|
-
name:
|
180
|
+
name: railties
|
175
181
|
requirement: !ruby/object:Gem::Requirement
|
176
182
|
requirements:
|
177
|
-
- - "
|
183
|
+
- - ">="
|
178
184
|
- !ruby/object:Gem::Version
|
179
|
-
version: '
|
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: '
|
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/
|
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.
|
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
|
-
|
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
|