rack-attack 6.6.1 → 6.8.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 +12 -8
- data/lib/rack/attack/base_proxy.rb +1 -0
- data/lib/rack/attack/cache.rb +10 -4
- data/lib/rack/attack/configuration.rb +7 -3
- data/lib/rack/attack/path_normalizer.rb +3 -1
- data/lib/rack/attack/railtie.rb +6 -0
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +16 -10
- data/lib/rack/attack/store_proxy/redis_proxy.rb +2 -1
- data/lib/rack/attack/throttle.rb +2 -1
- data/lib/rack/attack/version.rb +1 -1
- data/lib/rack/attack.rb +3 -1
- data/spec/acceptance/blocking_ip_spec.rb +13 -8
- data/spec/acceptance/blocking_spec.rb +16 -18
- data/spec/acceptance/blocking_subnet_spec.rb +7 -8
- data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +5 -3
- data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +7 -5
- data/spec/acceptance/cache_store_config_for_throttle_spec.rb +5 -3
- data/spec/acceptance/cache_store_config_with_rails_spec.rb +6 -4
- data/spec/acceptance/extending_request_object_spec.rb +3 -7
- data/spec/acceptance/fail2ban_spec.rb +42 -0
- data/spec/acceptance/rails_middleware_spec.rb +1 -1
- data/spec/acceptance/safelisting_ip_spec.rb +12 -4
- data/spec/acceptance/safelisting_spec.rb +14 -14
- data/spec/acceptance/safelisting_subnet_spec.rb +6 -4
- data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +5 -2
- data/spec/acceptance/stores/active_support_mem_cache_store_spec.rb +0 -1
- data/spec/acceptance/stores/active_support_memory_store_spec.rb +0 -2
- data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +5 -2
- data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +0 -1
- data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +0 -1
- data/spec/acceptance/stores/dalli_client_spec.rb +0 -1
- data/spec/acceptance/stores/redis_spec.rb +0 -1
- data/spec/acceptance/stores/redis_store_spec.rb +1 -3
- data/spec/acceptance/throttling_spec.rb +14 -23
- data/spec/acceptance/track_spec.rb +8 -9
- data/spec/acceptance/track_throttle_spec.rb +10 -16
- data/spec/configuration_spec.rb +33 -0
- data/spec/integration/offline_spec.rb +0 -12
- data/spec/rack_attack_instrumentation_spec.rb +25 -28
- data/spec/rack_attack_request_spec.rb +2 -4
- data/spec/rack_attack_reset_spec.rb +90 -0
- data/spec/rack_attack_spec.rb +4 -22
- data/spec/rack_attack_throttle_spec.rb +49 -28
- data/spec/rack_attack_track_spec.rb +4 -17
- data/spec/spec_helper.rb +7 -5
- data/spec/support/cache_store_helper.rb +31 -25
- data/spec/support/freeze_time_helper.rb +9 -0
- metadata +48 -28
- data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +0 -39
- data/spec/acceptance/stores/active_support_dalli_store_spec.rb +0 -25
- data/spec/acceptance/stores/active_support_redis_store_spec.rb +0 -20
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'spec_helper'
|
4
|
+
require_relative 'support/freeze_time_helper'
|
4
5
|
|
5
6
|
describe 'Rack::Attack.throttle' do
|
6
7
|
before do
|
7
|
-
@period = 60
|
8
|
+
@period = 60
|
8
9
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
9
10
|
Rack::Attack.throttle('ip/sec', limit: 1, period: @period) { |req| req.ip }
|
10
11
|
end
|
@@ -14,14 +15,18 @@ describe 'Rack::Attack.throttle' do
|
|
14
15
|
it_allows_ok_requests
|
15
16
|
|
16
17
|
describe 'a single request' do
|
17
|
-
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
18
|
-
|
19
18
|
it 'should set the counter for one request' do
|
20
|
-
|
21
|
-
|
19
|
+
within_same_period do
|
20
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
21
|
+
|
22
|
+
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
23
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
24
|
+
end
|
22
25
|
end
|
23
26
|
|
24
27
|
it 'should populate throttle data' do
|
28
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
29
|
+
|
25
30
|
data = {
|
26
31
|
count: 1,
|
27
32
|
limit: 1,
|
@@ -36,7 +41,9 @@ describe 'Rack::Attack.throttle' do
|
|
36
41
|
|
37
42
|
describe "with 2 requests" do
|
38
43
|
before do
|
39
|
-
|
44
|
+
within_same_period do
|
45
|
+
2.times { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
46
|
+
end
|
40
47
|
end
|
41
48
|
|
42
49
|
it 'should block the last request' do
|
@@ -62,7 +69,7 @@ end
|
|
62
69
|
|
63
70
|
describe 'Rack::Attack.throttle with limit as proc' do
|
64
71
|
before do
|
65
|
-
@period = 60
|
72
|
+
@period = 60
|
66
73
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
67
74
|
Rack::Attack.throttle('ip/sec', limit: lambda { |_req| 1 }, period: @period) { |req| req.ip }
|
68
75
|
end
|
@@ -70,14 +77,17 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
|
70
77
|
it_allows_ok_requests
|
71
78
|
|
72
79
|
describe 'a single request' do
|
73
|
-
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
74
|
-
|
75
80
|
it 'should set the counter for one request' do
|
76
|
-
|
77
|
-
|
81
|
+
within_same_period do
|
82
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
83
|
+
|
84
|
+
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
85
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
86
|
+
end
|
78
87
|
end
|
79
88
|
|
80
89
|
it 'should populate throttle data' do
|
90
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
81
91
|
data = {
|
82
92
|
count: 1,
|
83
93
|
limit: 1,
|
@@ -93,7 +103,7 @@ end
|
|
93
103
|
|
94
104
|
describe 'Rack::Attack.throttle with period as proc' do
|
95
105
|
before do
|
96
|
-
@period = 60
|
106
|
+
@period = 60
|
97
107
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
98
108
|
Rack::Attack.throttle('ip/sec', limit: lambda { |_req| 1 }, period: lambda { |_req| @period }) { |req| req.ip }
|
99
109
|
end
|
@@ -101,14 +111,18 @@ describe 'Rack::Attack.throttle with period as proc' do
|
|
101
111
|
it_allows_ok_requests
|
102
112
|
|
103
113
|
describe 'a single request' do
|
104
|
-
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
105
|
-
|
106
114
|
it 'should set the counter for one request' do
|
107
|
-
|
108
|
-
|
115
|
+
within_same_period do
|
116
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
117
|
+
|
118
|
+
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
119
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
120
|
+
end
|
109
121
|
end
|
110
122
|
|
111
123
|
it 'should populate throttle data' do
|
124
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
125
|
+
|
112
126
|
data = {
|
113
127
|
count: 1,
|
114
128
|
limit: 1,
|
@@ -122,7 +136,7 @@ describe 'Rack::Attack.throttle with period as proc' do
|
|
122
136
|
end
|
123
137
|
end
|
124
138
|
|
125
|
-
describe 'Rack::Attack.throttle with block
|
139
|
+
describe 'Rack::Attack.throttle with block returning nil' do
|
126
140
|
before do
|
127
141
|
@period = 60
|
128
142
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
@@ -132,14 +146,17 @@ describe 'Rack::Attack.throttle with block retuning nil' do
|
|
132
146
|
it_allows_ok_requests
|
133
147
|
|
134
148
|
describe 'a single request' do
|
135
|
-
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
136
|
-
|
137
149
|
it 'should not set the counter' do
|
138
|
-
|
139
|
-
|
150
|
+
within_same_period do
|
151
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
152
|
+
|
153
|
+
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
154
|
+
assert_nil Rack::Attack.cache.store.read(key)
|
155
|
+
end
|
140
156
|
end
|
141
157
|
|
142
158
|
it 'should not populate throttle data' do
|
159
|
+
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
143
160
|
assert_nil last_request.env['rack.attack.throttle_data']
|
144
161
|
end
|
145
162
|
end
|
@@ -162,9 +179,11 @@ describe 'Rack::Attack.throttle with throttle_discriminator_normalizer' do
|
|
162
179
|
end
|
163
180
|
|
164
181
|
it 'should not differentiate requests when throttle_discriminator_normalizer is enabled' do
|
165
|
-
|
166
|
-
|
167
|
-
|
182
|
+
within_same_period do
|
183
|
+
post_logins
|
184
|
+
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:person@example.com"
|
185
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 3
|
186
|
+
end
|
168
187
|
end
|
169
188
|
|
170
189
|
it 'should differentiate requests when throttle_discriminator_normalizer is disabled' do
|
@@ -172,10 +191,12 @@ describe 'Rack::Attack.throttle with throttle_discriminator_normalizer' do
|
|
172
191
|
prev = Rack::Attack.throttle_discriminator_normalizer
|
173
192
|
Rack::Attack.throttle_discriminator_normalizer = nil
|
174
193
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
194
|
+
within_same_period do
|
195
|
+
post_logins
|
196
|
+
@emails.each do |email|
|
197
|
+
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:#{email}"
|
198
|
+
_(Rack::Attack.cache.store.read(key)).must_equal 1
|
199
|
+
end
|
179
200
|
end
|
180
201
|
ensure
|
181
202
|
Rack::Attack.throttle_discriminator_normalizer = prev
|
@@ -3,19 +3,7 @@
|
|
3
3
|
require_relative 'spec_helper'
|
4
4
|
|
5
5
|
describe 'Rack::Attack.track' do
|
6
|
-
|
7
|
-
def self.incr
|
8
|
-
@counter += 1
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.reset
|
12
|
-
@counter = 0
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.check
|
16
|
-
@counter
|
17
|
-
end
|
18
|
-
end
|
6
|
+
let(:notifications) { [] }
|
19
7
|
|
20
8
|
before do
|
21
9
|
Rack::Attack.track("everything") { |_req| true }
|
@@ -32,19 +20,18 @@ describe 'Rack::Attack.track' do
|
|
32
20
|
|
33
21
|
describe "with a notification subscriber and two tracks" do
|
34
22
|
before do
|
35
|
-
Counter.reset
|
36
23
|
# A second track
|
37
24
|
Rack::Attack.track("homepage") { |req| req.path == "/" }
|
38
25
|
|
39
|
-
ActiveSupport::Notifications.subscribe("track.rack_attack") do
|
40
|
-
|
26
|
+
ActiveSupport::Notifications.subscribe("track.rack_attack") do |_name, _start, _finish, _id, payload|
|
27
|
+
notifications.push(payload)
|
41
28
|
end
|
42
29
|
|
43
30
|
get "/"
|
44
31
|
end
|
45
32
|
|
46
33
|
it "should notify twice" do
|
47
|
-
_(
|
34
|
+
_(notifications.size).must_equal 2
|
48
35
|
end
|
49
36
|
end
|
50
37
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
|
5
|
+
require "logger"
|
5
6
|
require "minitest/autorun"
|
6
7
|
require "minitest/pride"
|
7
8
|
require "rack/test"
|
8
|
-
require "
|
9
|
-
|
9
|
+
require "active_support"
|
10
10
|
require "rack/attack"
|
11
11
|
|
12
12
|
if RUBY_ENGINE == "ruby"
|
@@ -21,15 +21,17 @@ end
|
|
21
21
|
|
22
22
|
safe_require "connection_pool"
|
23
23
|
safe_require "dalli"
|
24
|
+
safe_require "rails"
|
24
25
|
safe_require "redis"
|
25
|
-
safe_require "redis-activesupport"
|
26
26
|
safe_require "redis-store"
|
27
27
|
|
28
|
-
class
|
28
|
+
class Minitest::Spec
|
29
29
|
include Rack::Test::Methods
|
30
30
|
|
31
31
|
before do
|
32
|
-
Rails.cache
|
32
|
+
if Object.const_defined?(:Rails) && Rails.respond_to?(:cache) && Rails.cache.respond_to?(:clear)
|
33
|
+
Rails.cache.clear
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
after do
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'freeze_time_helper'
|
4
|
+
|
3
5
|
class Minitest::Spec
|
4
6
|
def self.it_works_for_cache_backed_features(options)
|
5
7
|
fetch_from_store = options.fetch(:fetch_from_store)
|
@@ -9,11 +11,13 @@ class Minitest::Spec
|
|
9
11
|
request.ip
|
10
12
|
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
within_same_period do
|
15
|
+
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
16
|
+
assert_equal 200, last_response.status
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
19
|
+
assert_equal 429, last_response.status
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
it "works for fail2ban" do
|
@@ -23,17 +27,19 @@ class Minitest::Spec
|
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
|
-
|
27
|
-
|
30
|
+
within_same_period do
|
31
|
+
get "/"
|
32
|
+
assert_equal 200, last_response.status
|
28
33
|
|
29
|
-
|
30
|
-
|
34
|
+
get "/private-place"
|
35
|
+
assert_equal 403, last_response.status
|
31
36
|
|
32
|
-
|
33
|
-
|
37
|
+
get "/private-place"
|
38
|
+
assert_equal 403, last_response.status
|
34
39
|
|
35
|
-
|
36
|
-
|
40
|
+
get "/"
|
41
|
+
assert_equal 403, last_response.status
|
42
|
+
end
|
37
43
|
end
|
38
44
|
|
39
45
|
it "works for allow2ban" do
|
@@ -43,20 +49,22 @@ class Minitest::Spec
|
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
46
|
-
|
47
|
-
|
52
|
+
within_same_period do
|
53
|
+
get "/"
|
54
|
+
assert_equal 200, last_response.status
|
48
55
|
|
49
|
-
|
50
|
-
|
56
|
+
get "/scarce-resource"
|
57
|
+
assert_equal 200, last_response.status
|
51
58
|
|
52
|
-
|
53
|
-
|
59
|
+
get "/scarce-resource"
|
60
|
+
assert_equal 200, last_response.status
|
54
61
|
|
55
|
-
|
56
|
-
|
62
|
+
get "/scarce-resource"
|
63
|
+
assert_equal 403, last_response.status
|
57
64
|
|
58
|
-
|
59
|
-
|
65
|
+
get "/"
|
66
|
+
assert_equal 403, last_response.status
|
67
|
+
end
|
60
68
|
end
|
61
69
|
|
62
70
|
it "doesn't leak keys" do
|
@@ -66,9 +74,7 @@ class Minitest::Spec
|
|
66
74
|
|
67
75
|
key = nil
|
68
76
|
|
69
|
-
|
70
|
-
# we pre-calculate in local variable `key`
|
71
|
-
Timecop.freeze do
|
77
|
+
within_same_period do
|
72
78
|
key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
|
73
79
|
|
74
80
|
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-attack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Suggs
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rack
|
@@ -19,7 +18,7 @@ dependencies:
|
|
19
18
|
version: '1.0'
|
20
19
|
- - "<"
|
21
20
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
21
|
+
version: '4'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +28,7 @@ dependencies:
|
|
29
28
|
version: '1.0'
|
30
29
|
- - "<"
|
31
30
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
31
|
+
version: '4'
|
33
32
|
- !ruby/object:Gem::Dependency
|
34
33
|
name: appraisal
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,14 +97,14 @@ dependencies:
|
|
98
97
|
requirements:
|
99
98
|
- - "~>"
|
100
99
|
- !ruby/object:Gem::Version
|
101
|
-
version: '
|
100
|
+
version: '2.0'
|
102
101
|
type: :development
|
103
102
|
prerelease: false
|
104
103
|
version_requirements: !ruby/object:Gem::Requirement
|
105
104
|
requirements:
|
106
105
|
- - "~>"
|
107
106
|
- !ruby/object:Gem::Version
|
108
|
-
version: '
|
107
|
+
version: '2.0'
|
109
108
|
- !ruby/object:Gem::Dependency
|
110
109
|
name: rake
|
111
110
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,28 +125,56 @@ dependencies:
|
|
126
125
|
requirements:
|
127
126
|
- - '='
|
128
127
|
- !ruby/object:Gem::Version
|
129
|
-
version:
|
128
|
+
version: 1.12.1
|
130
129
|
type: :development
|
131
130
|
prerelease: false
|
132
131
|
version_requirements: !ruby/object:Gem::Requirement
|
133
132
|
requirements:
|
134
133
|
- - '='
|
135
134
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
135
|
+
version: 1.12.1
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: rubocop-minitest
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 0.11.1
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 0.11.1
|
137
150
|
- !ruby/object:Gem::Dependency
|
138
151
|
name: rubocop-performance
|
139
152
|
requirement: !ruby/object:Gem::Requirement
|
140
153
|
requirements:
|
141
154
|
- - "~>"
|
142
155
|
- !ruby/object:Gem::Version
|
143
|
-
version: 1.
|
156
|
+
version: 1.10.2
|
157
|
+
type: :development
|
158
|
+
prerelease: false
|
159
|
+
version_requirements: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: 1.10.2
|
164
|
+
- !ruby/object:Gem::Dependency
|
165
|
+
name: rubocop-rake
|
166
|
+
requirement: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - "~>"
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: 0.5.1
|
144
171
|
type: :development
|
145
172
|
prerelease: false
|
146
173
|
version_requirements: !ruby/object:Gem::Requirement
|
147
174
|
requirements:
|
148
175
|
- - "~>"
|
149
176
|
- !ruby/object:Gem::Version
|
150
|
-
version:
|
177
|
+
version: 0.5.1
|
151
178
|
- !ruby/object:Gem::Dependency
|
152
179
|
name: timecop
|
153
180
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,25 +204,19 @@ dependencies:
|
|
177
204
|
- !ruby/object:Gem::Version
|
178
205
|
version: '11.0'
|
179
206
|
- !ruby/object:Gem::Dependency
|
180
|
-
name:
|
207
|
+
name: activesupport
|
181
208
|
requirement: !ruby/object:Gem::Requirement
|
182
209
|
requirements:
|
183
210
|
- - ">="
|
184
211
|
- !ruby/object:Gem::Version
|
185
|
-
version: '
|
186
|
-
- - "<"
|
187
|
-
- !ruby/object:Gem::Version
|
188
|
-
version: '7.1'
|
212
|
+
version: '0'
|
189
213
|
type: :development
|
190
214
|
prerelease: false
|
191
215
|
version_requirements: !ruby/object:Gem::Requirement
|
192
216
|
requirements:
|
193
217
|
- - ">="
|
194
218
|
- !ruby/object:Gem::Version
|
195
|
-
version: '
|
196
|
-
- - "<"
|
197
|
-
- !ruby/object:Gem::Version
|
198
|
-
version: '7.1'
|
219
|
+
version: '0'
|
199
220
|
description: A rack middleware for throttling and blocking abusive requests
|
200
221
|
email: aaron@ktheory.com
|
201
222
|
executables: []
|
@@ -217,7 +238,6 @@ files:
|
|
217
238
|
- lib/rack/attack/railtie.rb
|
218
239
|
- lib/rack/attack/request.rb
|
219
240
|
- lib/rack/attack/safelist.rb
|
220
|
-
- lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb
|
221
241
|
- lib/rack/attack/store_proxy/dalli_proxy.rb
|
222
242
|
- lib/rack/attack/store_proxy/mem_cache_store_proxy.rb
|
223
243
|
- lib/rack/attack/store_proxy/redis_cache_store_proxy.rb
|
@@ -242,13 +262,11 @@ files:
|
|
242
262
|
- spec/acceptance/safelisting_ip_spec.rb
|
243
263
|
- spec/acceptance/safelisting_spec.rb
|
244
264
|
- spec/acceptance/safelisting_subnet_spec.rb
|
245
|
-
- spec/acceptance/stores/active_support_dalli_store_spec.rb
|
246
265
|
- spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb
|
247
266
|
- spec/acceptance/stores/active_support_mem_cache_store_spec.rb
|
248
267
|
- spec/acceptance/stores/active_support_memory_store_spec.rb
|
249
268
|
- spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb
|
250
269
|
- spec/acceptance/stores/active_support_redis_cache_store_spec.rb
|
251
|
-
- spec/acceptance/stores/active_support_redis_store_spec.rb
|
252
270
|
- spec/acceptance/stores/connection_pool_dalli_client_spec.rb
|
253
271
|
- spec/acceptance/stores/dalli_client_spec.rb
|
254
272
|
- spec/acceptance/stores/redis_spec.rb
|
@@ -257,17 +275,20 @@ files:
|
|
257
275
|
- spec/acceptance/track_spec.rb
|
258
276
|
- spec/acceptance/track_throttle_spec.rb
|
259
277
|
- spec/allow2ban_spec.rb
|
278
|
+
- spec/configuration_spec.rb
|
260
279
|
- spec/fail2ban_spec.rb
|
261
280
|
- spec/integration/offline_spec.rb
|
262
281
|
- spec/rack_attack_dalli_proxy_spec.rb
|
263
282
|
- spec/rack_attack_instrumentation_spec.rb
|
264
283
|
- spec/rack_attack_path_normalizer_spec.rb
|
265
284
|
- spec/rack_attack_request_spec.rb
|
285
|
+
- spec/rack_attack_reset_spec.rb
|
266
286
|
- spec/rack_attack_spec.rb
|
267
287
|
- spec/rack_attack_throttle_spec.rb
|
268
288
|
- spec/rack_attack_track_spec.rb
|
269
289
|
- spec/spec_helper.rb
|
270
290
|
- spec/support/cache_store_helper.rb
|
291
|
+
- spec/support/freeze_time_helper.rb
|
271
292
|
homepage: https://github.com/rack/rack-attack
|
272
293
|
licenses:
|
273
294
|
- MIT
|
@@ -275,7 +296,6 @@ metadata:
|
|
275
296
|
bug_tracker_uri: https://github.com/rack/rack-attack/issues
|
276
297
|
changelog_uri: https://github.com/rack/rack-attack/blob/main/CHANGELOG.md
|
277
298
|
source_code_uri: https://github.com/rack/rack-attack
|
278
|
-
post_install_message:
|
279
299
|
rdoc_options:
|
280
300
|
- "--charset=UTF-8"
|
281
301
|
require_paths:
|
@@ -291,8 +311,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
291
311
|
- !ruby/object:Gem::Version
|
292
312
|
version: '0'
|
293
313
|
requirements: []
|
294
|
-
rubygems_version: 3.
|
295
|
-
signing_key:
|
314
|
+
rubygems_version: 3.6.9
|
296
315
|
specification_version: 4
|
297
316
|
summary: Block & throttle abusive requests
|
298
317
|
test_files:
|
@@ -312,13 +331,11 @@ test_files:
|
|
312
331
|
- spec/acceptance/safelisting_ip_spec.rb
|
313
332
|
- spec/acceptance/safelisting_spec.rb
|
314
333
|
- spec/acceptance/safelisting_subnet_spec.rb
|
315
|
-
- spec/acceptance/stores/active_support_dalli_store_spec.rb
|
316
334
|
- spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb
|
317
335
|
- spec/acceptance/stores/active_support_mem_cache_store_spec.rb
|
318
336
|
- spec/acceptance/stores/active_support_memory_store_spec.rb
|
319
337
|
- spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb
|
320
338
|
- spec/acceptance/stores/active_support_redis_cache_store_spec.rb
|
321
|
-
- spec/acceptance/stores/active_support_redis_store_spec.rb
|
322
339
|
- spec/acceptance/stores/connection_pool_dalli_client_spec.rb
|
323
340
|
- spec/acceptance/stores/dalli_client_spec.rb
|
324
341
|
- spec/acceptance/stores/redis_spec.rb
|
@@ -327,14 +344,17 @@ test_files:
|
|
327
344
|
- spec/acceptance/track_spec.rb
|
328
345
|
- spec/acceptance/track_throttle_spec.rb
|
329
346
|
- spec/allow2ban_spec.rb
|
347
|
+
- spec/configuration_spec.rb
|
330
348
|
- spec/fail2ban_spec.rb
|
331
349
|
- spec/integration/offline_spec.rb
|
332
350
|
- spec/rack_attack_dalli_proxy_spec.rb
|
333
351
|
- spec/rack_attack_instrumentation_spec.rb
|
334
352
|
- spec/rack_attack_path_normalizer_spec.rb
|
335
353
|
- spec/rack_attack_request_spec.rb
|
354
|
+
- spec/rack_attack_reset_spec.rb
|
336
355
|
- spec/rack_attack_spec.rb
|
337
356
|
- spec/rack_attack_throttle_spec.rb
|
338
357
|
- spec/rack_attack_track_spec.rb
|
339
358
|
- spec/spec_helper.rb
|
340
359
|
- spec/support/cache_store_helper.rb
|
360
|
+
- spec/support/freeze_time_helper.rb
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rack/attack/base_proxy'
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
class Attack
|
7
|
-
module StoreProxy
|
8
|
-
class ActiveSupportRedisStoreProxy < BaseProxy
|
9
|
-
def self.handle?(store)
|
10
|
-
defined?(::Redis) &&
|
11
|
-
defined?(::ActiveSupport::Cache::RedisStore) &&
|
12
|
-
store.is_a?(::ActiveSupport::Cache::RedisStore)
|
13
|
-
end
|
14
|
-
|
15
|
-
def increment(name, amount = 1, options = {})
|
16
|
-
# #increment ignores options[:expires_in].
|
17
|
-
#
|
18
|
-
# So in order to workaround this we use #write (which sets expiration) to initialize
|
19
|
-
# the counter. After that we continue using the original #increment.
|
20
|
-
if options[:expires_in] && !read(name)
|
21
|
-
write(name, amount, options)
|
22
|
-
|
23
|
-
amount
|
24
|
-
else
|
25
|
-
super
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def read(name, options = {})
|
30
|
-
super(name, options.merge!(raw: true))
|
31
|
-
end
|
32
|
-
|
33
|
-
def write(name, value, options = {})
|
34
|
-
super(name, value, options.merge!(raw: true))
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../../spec_helper"
|
4
|
-
|
5
|
-
should_run =
|
6
|
-
defined?(::Dalli) &&
|
7
|
-
Gem::Version.new(::Dalli::VERSION) < Gem::Version.new("3")
|
8
|
-
|
9
|
-
if should_run
|
10
|
-
require_relative "../../support/cache_store_helper"
|
11
|
-
require "active_support/cache/dalli_store"
|
12
|
-
require "timecop"
|
13
|
-
|
14
|
-
describe "ActiveSupport::Cache::DalliStore as a cache backend" do
|
15
|
-
before do
|
16
|
-
Rack::Attack.cache.store = ActiveSupport::Cache::DalliStore.new
|
17
|
-
end
|
18
|
-
|
19
|
-
after do
|
20
|
-
Rack::Attack.cache.store.clear
|
21
|
-
end
|
22
|
-
|
23
|
-
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.fetch(key) })
|
24
|
-
end
|
25
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../../spec_helper"
|
4
|
-
|
5
|
-
if defined?(::ActiveSupport::Cache::RedisStore)
|
6
|
-
require_relative "../../support/cache_store_helper"
|
7
|
-
require "timecop"
|
8
|
-
|
9
|
-
describe "ActiveSupport::Cache::RedisStore as a cache backend" do
|
10
|
-
before do
|
11
|
-
Rack::Attack.cache.store = ActiveSupport::Cache::RedisStore.new
|
12
|
-
end
|
13
|
-
|
14
|
-
after do
|
15
|
-
Rack::Attack.cache.store.clear
|
16
|
-
end
|
17
|
-
|
18
|
-
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.read(key) })
|
19
|
-
end
|
20
|
-
end
|