rack-attack 5.3.0 → 5.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +4 -1
- data/lib/rack/attack.rb +4 -4
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +13 -8
- data/lib/rack/attack/version.rb +1 -1
- data/spec/acceptance/stores/redis_cache_store_pooled_spec.rb +40 -0
- data/spec/rack_attack_throttle_spec.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f06d0fae1f4dc5d960274ca06a4da7be66a1180a3df051595c98813296e80e46
|
4
|
+
data.tar.gz: 32fa128bb61140836c8fcce73d1cd972c3987405e581a43dea2334d6ba05cfa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d7be10e1ddb908f07fb10aec414f47fcb9d23289eacd98a1a91e1f87ffa0212d63f424fff44bcfa0b0154263518d807e535bcd8791200c8dc290ea31bd4395e
|
7
|
+
data.tar.gz: c99bfe7df1e11591e80526fd17b414494ddaa797906a4cced2beca884fe51db9fe9ce9d4dd99ee92ac98921a35f87361944ca4d8895b83a86ccc442b6d5cae31
|
data/Rakefile
CHANGED
@@ -2,6 +2,9 @@ require "rubygems"
|
|
2
2
|
require "bundler/setup"
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rake/testtask'
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
|
7
|
+
RuboCop::RakeTask.new
|
5
8
|
|
6
9
|
namespace :test do
|
7
10
|
Rake::TestTask.new(:units) do |t|
|
@@ -20,4 +23,4 @@ end
|
|
20
23
|
desc 'Run tests'
|
21
24
|
task :test => %w[test:units test:integration test:acceptance]
|
22
25
|
|
23
|
-
task :default => :test
|
26
|
+
task :default => [:rubocop, :test]
|
data/lib/rack/attack.rb
CHANGED
@@ -38,15 +38,15 @@ class Rack::Attack
|
|
38
38
|
self.blocklists[name] = Blocklist.new(name, block)
|
39
39
|
end
|
40
40
|
|
41
|
-
def blocklist_ip(
|
41
|
+
def blocklist_ip(ip_address)
|
42
42
|
@ip_blocklists ||= []
|
43
|
-
ip_blocklist_proc = lambda { |request| IPAddr.new(
|
43
|
+
ip_blocklist_proc = lambda { |request| IPAddr.new(ip_address).include?(IPAddr.new(request.ip)) }
|
44
44
|
@ip_blocklists << Blocklist.new(nil, ip_blocklist_proc)
|
45
45
|
end
|
46
46
|
|
47
|
-
def safelist_ip(
|
47
|
+
def safelist_ip(ip_address)
|
48
48
|
@ip_safelists ||= []
|
49
|
-
ip_safelist_proc = lambda { |request| IPAddr.new(
|
49
|
+
ip_safelist_proc = lambda { |request| IPAddr.new(ip_address).include?(IPAddr.new(request.ip)) }
|
50
50
|
@ip_safelists << Safelist.new(nil, ip_safelist_proc)
|
51
51
|
end
|
52
52
|
|
@@ -8,21 +8,26 @@ module Rack
|
|
8
8
|
defined?(::ActiveSupport::Cache::RedisCacheStore) && store.is_a?(::ActiveSupport::Cache::RedisCacheStore)
|
9
9
|
end
|
10
10
|
|
11
|
-
def increment(name, amount, options = {})
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def increment(name, amount = 1, options = {})
|
12
|
+
# RedisCacheStore#increment ignores options[:expires_in].
|
13
|
+
#
|
14
|
+
# So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
|
15
|
+
# the counter. After that we continue using the original RedisCacheStore#increment.
|
16
|
+
if options[:expires_in] && !read(name)
|
17
|
+
write(name, amount, options)
|
18
|
+
|
19
|
+
1
|
20
|
+
else
|
21
|
+
super
|
16
22
|
end
|
17
|
-
count.first
|
18
23
|
end
|
19
24
|
|
20
25
|
def read(name, options = {})
|
21
|
-
super(name, options.merge!(
|
26
|
+
super(name, options.merge!(raw: true))
|
22
27
|
end
|
23
28
|
|
24
29
|
def write(name, value, options = {})
|
25
|
-
super(name, value, options.merge!(
|
30
|
+
super(name, value, options.merge!(raw: true))
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
data/lib/rack/attack/version.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "../../spec_helper"
|
2
|
+
require_relative "../../support/cache_store_helper"
|
3
|
+
|
4
|
+
require "timecop"
|
5
|
+
|
6
|
+
if ActiveSupport.version >= Gem::Version.new("5.2.0")
|
7
|
+
describe "RedisCacheStore (pooled) as a cache backend" do
|
8
|
+
before do
|
9
|
+
Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new(pool_size: 2)
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
Rack::Attack.cache.store.clear
|
14
|
+
end
|
15
|
+
|
16
|
+
it_works_for_cache_backed_features
|
17
|
+
|
18
|
+
it "doesn't leak keys" do
|
19
|
+
Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
|
20
|
+
request.ip
|
21
|
+
end
|
22
|
+
|
23
|
+
key = nil
|
24
|
+
|
25
|
+
# Freeze time during these statement to be sure that the key used by rack attack is the same
|
26
|
+
# we pre-calculate in local variable `key`
|
27
|
+
Timecop.freeze do
|
28
|
+
key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
|
29
|
+
|
30
|
+
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
31
|
+
end
|
32
|
+
|
33
|
+
assert Rack::Attack.cache.store.fetch(key)
|
34
|
+
|
35
|
+
sleep 2.1
|
36
|
+
|
37
|
+
assert_nil Rack::Attack.cache.store.fetch(key)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -37,7 +37,7 @@ describe 'Rack::Attack.throttle' do
|
|
37
37
|
it 'should tag the env' do
|
38
38
|
last_request.env['rack.attack.matched'].must_equal 'ip/sec'
|
39
39
|
last_request.env['rack.attack.match_type'].must_equal :throttle
|
40
|
-
last_request.env['rack.attack.match_data'].must_equal(
|
40
|
+
last_request.env['rack.attack.match_data'].must_equal(:count => 2, :limit => 1, :period => @period)
|
41
41
|
last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
|
42
42
|
end
|
43
43
|
|
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.3.
|
4
|
+
version: 5.3.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-06-
|
11
|
+
date: 2018-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -212,14 +212,14 @@ dependencies:
|
|
212
212
|
requirements:
|
213
213
|
- - '='
|
214
214
|
- !ruby/object:Gem::Version
|
215
|
-
version: 0.
|
215
|
+
version: 0.57.2
|
216
216
|
type: :development
|
217
217
|
prerelease: false
|
218
218
|
version_requirements: !ruby/object:Gem::Requirement
|
219
219
|
requirements:
|
220
220
|
- - '='
|
221
221
|
- !ruby/object:Gem::Version
|
222
|
-
version: 0.
|
222
|
+
version: 0.57.2
|
223
223
|
- !ruby/object:Gem::Dependency
|
224
224
|
name: timecop
|
225
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -303,6 +303,7 @@ files:
|
|
303
303
|
- spec/acceptance/safelisting_spec.rb
|
304
304
|
- spec/acceptance/safelisting_subnet_spec.rb
|
305
305
|
- spec/acceptance/stores/mem_cache_store_spec.rb
|
306
|
+
- spec/acceptance/stores/redis_cache_store_pooled_spec.rb
|
306
307
|
- spec/acceptance/stores/redis_cache_store_spec.rb
|
307
308
|
- spec/acceptance/throttling_spec.rb
|
308
309
|
- spec/acceptance/track_spec.rb
|
@@ -367,6 +368,7 @@ test_files:
|
|
367
368
|
- spec/acceptance/fail2ban_spec.rb
|
368
369
|
- spec/acceptance/stores/mem_cache_store_spec.rb
|
369
370
|
- spec/acceptance/stores/redis_cache_store_spec.rb
|
371
|
+
- spec/acceptance/stores/redis_cache_store_pooled_spec.rb
|
370
372
|
- spec/acceptance/customizing_blocked_response_spec.rb
|
371
373
|
- spec/spec_helper.rb
|
372
374
|
- spec/allow2ban_spec.rb
|