rack-attack 6.1.0 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -2
- data/lib/rack/attack.rb +136 -124
- data/lib/rack/attack/cache.rb +4 -1
- data/lib/rack/attack/check.rb +2 -1
- data/lib/rack/attack/path_normalizer.rb +20 -18
- data/lib/rack/attack/railtie.rb +21 -0
- data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +3 -1
- data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +3 -1
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +22 -6
- data/lib/rack/attack/throttle.rb +3 -2
- data/lib/rack/attack/track.rb +6 -5
- data/lib/rack/attack/version.rb +1 -1
- data/spec/acceptance/rails_middleware_spec.rb +41 -0
- data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +1 -3
- data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +7 -1
- data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +6 -1
- data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +3 -3
- data/spec/allow2ban_spec.rb +17 -14
- data/spec/fail2ban_spec.rb +17 -16
- data/spec/rack_attack_instrumentation_spec.rb +1 -1
- data/spec/rack_attack_path_normalizer_spec.rb +2 -2
- data/spec/rack_attack_spec.rb +36 -13
- data/spec/rack_attack_throttle_spec.rb +12 -12
- data/spec/rack_attack_track_spec.rb +8 -5
- data/spec/spec_helper.rb +5 -4
- metadata +30 -21
@@ -18,7 +18,7 @@ describe 'Rack::Attack.throttle' do
|
|
18
18
|
|
19
19
|
it 'should set the counter for one request' do
|
20
20
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
21
|
-
Rack::Attack.cache.store.read(key).must_equal 1
|
21
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'should populate throttle data' do
|
@@ -30,7 +30,7 @@ describe 'Rack::Attack.throttle' do
|
|
30
30
|
discriminator: "1.2.3.4"
|
31
31
|
}
|
32
32
|
|
33
|
-
last_request.env['rack.attack.throttle_data']['ip/sec'].must_equal data
|
33
|
+
_(last_request.env['rack.attack.throttle_data']['ip/sec']).must_equal data
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -40,14 +40,14 @@ describe 'Rack::Attack.throttle' do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should block the last request' do
|
43
|
-
last_response.status.must_equal 429
|
43
|
+
_(last_response.status).must_equal 429
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'should tag the env' do
|
47
|
-
last_request.env['rack.attack.matched'].must_equal 'ip/sec'
|
48
|
-
last_request.env['rack.attack.match_type'].must_equal :throttle
|
47
|
+
_(last_request.env['rack.attack.matched']).must_equal 'ip/sec'
|
48
|
+
_(last_request.env['rack.attack.match_type']).must_equal :throttle
|
49
49
|
|
50
|
-
last_request.env['rack.attack.match_data'].must_equal(
|
50
|
+
_(last_request.env['rack.attack.match_data']).must_equal(
|
51
51
|
count: 2,
|
52
52
|
limit: 1,
|
53
53
|
period: @period,
|
@@ -55,11 +55,11 @@ describe 'Rack::Attack.throttle' do
|
|
55
55
|
discriminator: "1.2.3.4"
|
56
56
|
)
|
57
57
|
|
58
|
-
last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
|
58
|
+
_(last_request.env['rack.attack.match_discriminator']).must_equal('1.2.3.4')
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should set a Retry-After header' do
|
62
|
-
last_response.headers['Retry-After'].must_equal @period.to_s
|
62
|
+
_(last_response.headers['Retry-After']).must_equal @period.to_s
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -78,7 +78,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
|
78
78
|
|
79
79
|
it 'should set the counter for one request' do
|
80
80
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
81
|
-
Rack::Attack.cache.store.read(key).must_equal 1
|
81
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'should populate throttle data' do
|
@@ -90,7 +90,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
|
90
90
|
discriminator: "1.2.3.4"
|
91
91
|
}
|
92
92
|
|
93
|
-
last_request.env['rack.attack.throttle_data']['ip/sec'].must_equal data
|
93
|
+
_(last_request.env['rack.attack.throttle_data']['ip/sec']).must_equal data
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -109,7 +109,7 @@ describe 'Rack::Attack.throttle with period as proc' do
|
|
109
109
|
|
110
110
|
it 'should set the counter for one request' do
|
111
111
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
112
|
-
Rack::Attack.cache.store.read(key).must_equal 1
|
112
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
113
113
|
end
|
114
114
|
|
115
115
|
it 'should populate throttle data' do
|
@@ -121,7 +121,7 @@ describe 'Rack::Attack.throttle with period as proc' do
|
|
121
121
|
discriminator: "1.2.3.4"
|
122
122
|
}
|
123
123
|
|
124
|
-
last_request.env['rack.attack.throttle_data']['ip/sec'].must_equal data
|
124
|
+
_(last_request.env['rack.attack.throttle_data']['ip/sec']).must_equal data
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
@@ -25,8 +25,9 @@ describe 'Rack::Attack.track' do
|
|
25
25
|
|
26
26
|
it "should tag the env" do
|
27
27
|
get '/'
|
28
|
-
|
29
|
-
last_request.env['rack.attack.
|
28
|
+
|
29
|
+
_(last_request.env['rack.attack.matched']).must_equal 'everything'
|
30
|
+
_(last_request.env['rack.attack.match_type']).must_equal :track
|
30
31
|
end
|
31
32
|
|
32
33
|
describe "with a notification subscriber and two tracks" do
|
@@ -43,21 +44,23 @@ describe 'Rack::Attack.track' do
|
|
43
44
|
end
|
44
45
|
|
45
46
|
it "should notify twice" do
|
46
|
-
Counter.check.must_equal 2
|
47
|
+
_(Counter.check).must_equal 2
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
51
|
describe "without limit and period options" do
|
51
52
|
it "should assign the track filter to a Check instance" do
|
52
53
|
track = Rack::Attack.track("homepage") { |req| req.path == "/" }
|
53
|
-
|
54
|
+
|
55
|
+
_(track.filter.class).must_equal Rack::Attack::Check
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
57
59
|
describe "with limit and period options" do
|
58
60
|
it "should assign the track filter to a Throttle instance" do
|
59
61
|
track = Rack::Attack.track("homepage", limit: 10, period: 10) { |req| req.path == "/" }
|
60
|
-
|
62
|
+
|
63
|
+
_(track.filter.class).must_equal Rack::Attack::Throttle
|
61
64
|
end
|
62
65
|
end
|
63
66
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,8 +5,7 @@ require "bundler/setup"
|
|
5
5
|
require "minitest/autorun"
|
6
6
|
require "minitest/pride"
|
7
7
|
require "rack/test"
|
8
|
-
require
|
9
|
-
require 'action_dispatch'
|
8
|
+
require "rails"
|
10
9
|
|
11
10
|
require "rack/attack"
|
12
11
|
|
@@ -30,6 +29,7 @@ class MiniTest::Spec
|
|
30
29
|
include Rack::Test::Methods
|
31
30
|
|
32
31
|
before do
|
32
|
+
Rails.cache = nil
|
33
33
|
@_original_throttled_response = Rack::Attack.throttled_response
|
34
34
|
@_original_blocklisted_response = Rack::Attack.blocklisted_response
|
35
35
|
end
|
@@ -56,8 +56,9 @@ class MiniTest::Spec
|
|
56
56
|
def self.it_allows_ok_requests
|
57
57
|
it "must allow ok requests" do
|
58
58
|
get '/', {}, 'REMOTE_ADDR' => '127.0.0.1'
|
59
|
-
|
60
|
-
last_response.
|
59
|
+
|
60
|
+
_(last_response.status).must_equal 200
|
61
|
+
_(last_response.body).must_equal 'Hello World'
|
61
62
|
end
|
62
63
|
end
|
63
64
|
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.
|
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: 2019-
|
11
|
+
date: 2019-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -112,84 +112,90 @@ dependencies:
|
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: '
|
115
|
+
version: '13.0'
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: '
|
122
|
+
version: '13.0'
|
123
123
|
- !ruby/object:Gem::Dependency
|
124
124
|
name: rubocop
|
125
125
|
requirement: !ruby/object:Gem::Requirement
|
126
126
|
requirements:
|
127
127
|
- - '='
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: 0.
|
129
|
+
version: 0.75.0
|
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.
|
136
|
+
version: 0.75.0
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
|
-
name:
|
138
|
+
name: rubocop-performance
|
139
139
|
requirement: !ruby/object:Gem::Requirement
|
140
140
|
requirements:
|
141
141
|
- - "~>"
|
142
142
|
- !ruby/object:Gem::Version
|
143
|
-
version:
|
143
|
+
version: 1.5.0
|
144
144
|
type: :development
|
145
145
|
prerelease: false
|
146
146
|
version_requirements: !ruby/object:Gem::Requirement
|
147
147
|
requirements:
|
148
148
|
- - "~>"
|
149
149
|
- !ruby/object:Gem::Version
|
150
|
-
version:
|
150
|
+
version: 1.5.0
|
151
151
|
- !ruby/object:Gem::Dependency
|
152
|
-
name:
|
152
|
+
name: timecop
|
153
153
|
requirement: !ruby/object:Gem::Requirement
|
154
154
|
requirements:
|
155
155
|
- - "~>"
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
157
|
+
version: 0.9.1
|
158
158
|
type: :development
|
159
159
|
prerelease: false
|
160
160
|
version_requirements: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
162
|
- - "~>"
|
163
163
|
- !ruby/object:Gem::Version
|
164
|
-
version:
|
164
|
+
version: 0.9.1
|
165
165
|
- !ruby/object:Gem::Dependency
|
166
|
-
name:
|
166
|
+
name: byebug
|
167
167
|
requirement: !ruby/object:Gem::Requirement
|
168
168
|
requirements:
|
169
169
|
- - "~>"
|
170
170
|
- !ruby/object:Gem::Version
|
171
|
-
version: '
|
171
|
+
version: '11.0'
|
172
172
|
type: :development
|
173
173
|
prerelease: false
|
174
174
|
version_requirements: !ruby/object:Gem::Requirement
|
175
175
|
requirements:
|
176
176
|
- - "~>"
|
177
177
|
- !ruby/object:Gem::Version
|
178
|
-
version: '
|
178
|
+
version: '11.0'
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
|
-
name:
|
180
|
+
name: railties
|
181
181
|
requirement: !ruby/object:Gem::Requirement
|
182
182
|
requirements:
|
183
|
-
- - "
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '4.2'
|
186
|
+
- - "<"
|
184
187
|
- !ruby/object:Gem::Version
|
185
|
-
version: '
|
188
|
+
version: '6.1'
|
186
189
|
type: :development
|
187
190
|
prerelease: false
|
188
191
|
version_requirements: !ruby/object:Gem::Requirement
|
189
192
|
requirements:
|
190
|
-
- - "
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '4.2'
|
196
|
+
- - "<"
|
191
197
|
- !ruby/object:Gem::Version
|
192
|
-
version: '
|
198
|
+
version: '6.1'
|
193
199
|
description: A rack middleware for throttling and blocking abusive requests
|
194
200
|
email: aaron@ktheory.com
|
195
201
|
executables: []
|
@@ -206,6 +212,7 @@ files:
|
|
206
212
|
- lib/rack/attack/check.rb
|
207
213
|
- lib/rack/attack/fail2ban.rb
|
208
214
|
- lib/rack/attack/path_normalizer.rb
|
215
|
+
- lib/rack/attack/railtie.rb
|
209
216
|
- lib/rack/attack/request.rb
|
210
217
|
- lib/rack/attack/safelist.rb
|
211
218
|
- lib/rack/attack/store_proxy.rb
|
@@ -230,6 +237,7 @@ files:
|
|
230
237
|
- spec/acceptance/customizing_throttled_response_spec.rb
|
231
238
|
- spec/acceptance/extending_request_object_spec.rb
|
232
239
|
- spec/acceptance/fail2ban_spec.rb
|
240
|
+
- spec/acceptance/rails_middleware_spec.rb
|
233
241
|
- spec/acceptance/safelisting_ip_spec.rb
|
234
242
|
- spec/acceptance/safelisting_spec.rb
|
235
243
|
- spec/acceptance/safelisting_subnet_spec.rb
|
@@ -282,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
290
|
- !ruby/object:Gem::Version
|
283
291
|
version: '0'
|
284
292
|
requirements: []
|
285
|
-
rubygems_version: 3.0.
|
293
|
+
rubygems_version: 3.0.6
|
286
294
|
signing_key:
|
287
295
|
specification_version: 4
|
288
296
|
summary: Block & throttle abusive requests
|
@@ -290,6 +298,7 @@ test_files:
|
|
290
298
|
- spec/integration/offline_spec.rb
|
291
299
|
- spec/rack_attack_path_normalizer_spec.rb
|
292
300
|
- spec/acceptance/safelisting_subnet_spec.rb
|
301
|
+
- spec/acceptance/rails_middleware_spec.rb
|
293
302
|
- spec/acceptance/track_throttle_spec.rb
|
294
303
|
- spec/acceptance/cache_store_config_for_fail2ban_spec.rb
|
295
304
|
- spec/acceptance/cache_store_config_with_rails_spec.rb
|