rack-attack 6.5.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81f6cce465b8441782ffaa3d446e558979de6a2ceadd9d43499b7977fa61586b
4
- data.tar.gz: a2ee9b82f1144d483e7d26a893594ab6cada4dc52d98eb08d7615a38b49face8
3
+ metadata.gz: c87eb44c705e3cfd5e5724266185a989cd60c44333ad211f21789a6778f18ac1
4
+ data.tar.gz: 54761820c0b6dd8ef062d6cce59f1807d98a05e9f00ffa2eadf7e4258a557ed3
5
5
  SHA512:
6
- metadata.gz: b90fa7841d1e5319b820d4bca9c1fc8d266fc98c06f2a936ce6d31949d9fdd7ddab9183f82c5bbbc31e3e4280bba8e786bbe155f146fdcfdbf53ad263bfec63f
7
- data.tar.gz: c91be495fbf25444632a1734f40f9fa85b35bf19d921a129ca402aceadf0d30b2a7d5797283ca7ac68e8f323569fa3edc1be98bcecd2c72aa15c3956dd611455
6
+ metadata.gz: 4a9382dcf4a307716eb77a4d232a081e0354c8f81c78d71076518db9939daed4319fbf605714514438c538f8e0c75c99b90a6f261730d67831af66a0b7208f57
7
+ data.tar.gz: dc207b3c238721aee545025c12440ae83ab6d924ceaeecaaaaa25b84a546f579d3518476ca2f55d5839fc24170d1a0ae7b95bd424ed57b84c23f74afa271922b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2016 Kickstarter, PBC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- __Note__: You are viewing the development version README.
1
+ :warning: You are viewing the development's branch version of README which might contain documentation for unreleased features.
2
2
  For the README consistent with the latest released version see https://github.com/rack/rack-attack/blob/6-stable/README.md.
3
3
 
4
4
  # Rack::Attack
@@ -10,7 +10,7 @@ Protect your Rails and Rack apps from bad clients. Rack::Attack lets you easily
10
10
  See the [Backing & Hacking blog post](https://www.kickstarter.com/backing-and-hacking/rack-attack-protection-from-abusive-clients) introducing Rack::Attack.
11
11
 
12
12
  [![Gem Version](https://badge.fury.io/rb/rack-attack.svg)](https://badge.fury.io/rb/rack-attack)
13
- [![Build Status](https://travis-ci.org/rack/rack-attack.svg?branch=master)](https://travis-ci.org/rack/rack-attack)
13
+ [![build](https://github.com/rack/rack-attack/actions/workflows/build.yml/badge.svg)](https://github.com/rack/rack-attack/actions/workflows/build.yml)
14
14
  [![Code Climate](https://codeclimate.com/github/kickstarter/rack-attack.svg)](https://codeclimate.com/github/kickstarter/rack-attack)
15
15
  [![Join the chat at https://gitter.im/rack-attack/rack-attack](https://badges.gitter.im/rack-attack/rack-attack.svg)](https://gitter.im/rack-attack/rack-attack)
16
16
 
@@ -312,21 +312,21 @@ Note that `Rack::Attack.cache` is only used for throttling, allow2ban and fail2b
312
312
 
313
313
  ## Customizing responses
314
314
 
315
- Customize the response of blocklisted and throttled requests using an object that adheres to the [Rack app interface](http://www.rubydoc.info/github/rack/rack/file/SPEC).
315
+ Customize the response of blocklisted and throttled requests using an object that adheres to the [Rack app interface](http://www.rubydoc.info/github/rack/rack/file/SPEC.rdoc).
316
316
 
317
317
  ```ruby
318
- Rack::Attack.blocklisted_response = lambda do |env|
318
+ Rack::Attack.blocklisted_responder = lambda do |request|
319
319
  # Using 503 because it may make attacker think that they have successfully
320
320
  # DOSed the site. Rack::Attack returns 403 for blocklists by default
321
321
  [ 503, {}, ['Blocked']]
322
322
  end
323
323
 
324
- Rack::Attack.throttled_response = lambda do |env|
324
+ Rack::Attack.throttled_responder = lambda do |request|
325
325
  # NB: you have access to the name and other data about the matched throttle
326
- # env['rack.attack.matched'],
327
- # env['rack.attack.match_type'],
328
- # env['rack.attack.match_data'],
329
- # env['rack.attack.match_discriminator']
326
+ # request.env['rack.attack.matched'],
327
+ # request.env['rack.attack.match_type'],
328
+ # request.env['rack.attack.match_data'],
329
+ # request.env['rack.attack.match_discriminator']
330
330
 
331
331
  # Using 503 because it may make attacker think that they have successfully
332
332
  # DOSed the site. Rack::Attack returns 429 for throttling by default
@@ -407,7 +407,7 @@ for more on how to do this.
407
407
 
408
408
  ### Test case isolation
409
409
 
410
- `Rack::Attack.reset!` can be used in your test suite to clear any Rack::Attack state between different test cases.
410
+ `Rack::Attack.reset!` can be used in your test suite to clear any Rack::Attack state between different test cases. If you're testing blocklist and safelist configurations, consider using `Rack::Attack.clear_configuration` to unset the values for those lists between test cases.
411
411
 
412
412
  ## How it works
413
413
 
@@ -427,9 +427,9 @@ def call(env)
427
427
  if safelisted?(req)
428
428
  @app.call(env)
429
429
  elsif blocklisted?(req)
430
- self.class.blocklisted_response.call(env)
430
+ self.class.blocklisted_responder.call(req)
431
431
  elsif throttled?(req)
432
- self.class.throttled_response.call(env)
432
+ self.class.throttled_responder.call(req)
433
433
  else
434
434
  tracked?(req)
435
435
  @app.call(env)
@@ -5,11 +5,11 @@ require "ipaddr"
5
5
  module Rack
6
6
  class Attack
7
7
  class Configuration
8
- DEFAULT_BLOCKLISTED_RESPONSE = lambda { |_env| [403, { 'Content-Type' => 'text/plain' }, ["Forbidden\n"]] }
8
+ DEFAULT_BLOCKLISTED_RESPONDER = lambda { |_req| [403, { 'Content-Type' => 'text/plain' }, ["Forbidden\n"]] }
9
9
 
10
- DEFAULT_THROTTLED_RESPONSE = lambda do |env|
10
+ DEFAULT_THROTTLED_RESPONDER = lambda do |req|
11
11
  if Rack::Attack.configuration.throttled_response_retry_after_header
12
- match_data = env['rack.attack.match_data']
12
+ match_data = req.env['rack.attack.match_data']
13
13
  now = match_data[:epoch_time]
14
14
  retry_after = match_data[:period] - (now % match_data[:period])
15
15
 
@@ -20,7 +20,21 @@ module Rack
20
20
  end
21
21
 
22
22
  attr_reader :safelists, :blocklists, :throttles, :anonymous_blocklists, :anonymous_safelists
23
- attr_accessor :blocklisted_response, :throttled_response, :throttled_response_retry_after_header
23
+ attr_accessor :blocklisted_responder, :throttled_responder, :throttled_response_retry_after_header
24
+
25
+ attr_reader :blocklisted_response, :throttled_response # Keeping these for backwards compatibility
26
+
27
+ def blocklisted_response=(responder)
28
+ warn "[DEPRECATION] Rack::Attack.blocklisted_response is deprecated. "\
29
+ "Please use Rack::Attack.blocklisted_responder instead."
30
+ @blocklisted_response = responder
31
+ end
32
+
33
+ def throttled_response=(responder)
34
+ warn "[DEPRECATION] Rack::Attack.throttled_response is deprecated. "\
35
+ "Please use Rack::Attack.throttled_responder instead"
36
+ @throttled_response = responder
37
+ end
24
38
 
25
39
  def initialize
26
40
  set_defaults
@@ -99,8 +113,12 @@ module Rack
99
113
  @anonymous_safelists = []
100
114
  @throttled_response_retry_after_header = false
101
115
 
102
- @blocklisted_response = DEFAULT_BLOCKLISTED_RESPONSE
103
- @throttled_response = DEFAULT_THROTTLED_RESPONSE
116
+ @blocklisted_responder = DEFAULT_BLOCKLISTED_RESPONDER
117
+ @throttled_responder = DEFAULT_THROTTLED_RESPONDER
118
+
119
+ # Deprecated: Keeping these for backwards compatibility
120
+ @blocklisted_response = nil
121
+ @throttled_response = nil
104
122
  end
105
123
  end
106
124
  end
@@ -12,6 +12,10 @@ module Rack
12
12
  store.is_a?(::ActiveSupport::Cache::MemCacheStore)
13
13
  end
14
14
 
15
+ def read(name, options = {})
16
+ super(name, options.merge!(raw: true))
17
+ end
18
+
15
19
  def write(name, value, options = {})
16
20
  super(name, value, options.merge!(raw: true))
17
21
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class Attack
5
- VERSION = '6.5.0'
5
+ VERSION = '6.6.0'
6
6
  end
7
7
  end
data/lib/rack/attack.rb CHANGED
@@ -66,6 +66,10 @@ module Rack
66
66
  :safelist_ip,
67
67
  :throttle,
68
68
  :track,
69
+ :throttled_responder,
70
+ :throttled_responder=,
71
+ :blocklisted_responder,
72
+ :blocklisted_responder=,
69
73
  :blocklisted_response,
70
74
  :blocklisted_response=,
71
75
  :throttled_response,
@@ -105,9 +109,19 @@ module Rack
105
109
  if configuration.safelisted?(request)
106
110
  @app.call(env)
107
111
  elsif configuration.blocklisted?(request)
108
- configuration.blocklisted_response.call(env)
112
+ # Deprecated: Keeping blocklisted_response for backwards compatibility
113
+ if configuration.blocklisted_response
114
+ configuration.blocklisted_response.call(env)
115
+ else
116
+ configuration.blocklisted_responder.call(request)
117
+ end
109
118
  elsif configuration.throttled?(request)
110
- configuration.throttled_response.call(env)
119
+ # Deprecated: Keeping throttled_response for backwards compatibility
120
+ if configuration.throttled_response
121
+ configuration.throttled_response.call(env)
122
+ else
123
+ configuration.throttled_responder.call(request)
124
+ end
111
125
  else
112
126
  configuration.tracked?(request)
113
127
  @app.call(env)
@@ -14,7 +14,7 @@ describe "Customizing block responses" do
14
14
 
15
15
  assert_equal 403, last_response.status
16
16
 
17
- Rack::Attack.blocklisted_response = lambda do |_env|
17
+ Rack::Attack.blocklisted_responder = lambda do |_req|
18
18
  [503, {}, ["Blocked"]]
19
19
  end
20
20
 
@@ -28,9 +28,9 @@ describe "Customizing block responses" do
28
28
  matched = nil
29
29
  match_type = nil
30
30
 
31
- Rack::Attack.blocklisted_response = lambda do |env|
32
- matched = env['rack.attack.matched']
33
- match_type = env['rack.attack.match_type']
31
+ Rack::Attack.blocklisted_responder = lambda do |req|
32
+ matched = req.env['rack.attack.matched']
33
+ match_type = req.env['rack.attack.match_type']
34
34
 
35
35
  [503, {}, ["Blocked"]]
36
36
  end
@@ -40,4 +40,21 @@ describe "Customizing block responses" do
40
40
  assert_equal "block 1.2.3.4", matched
41
41
  assert_equal :blocklist, match_type
42
42
  end
43
+
44
+ it "supports old style" do
45
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
46
+
47
+ assert_equal 403, last_response.status
48
+
49
+ silence_warnings do
50
+ Rack::Attack.blocklisted_response = lambda do |_env|
51
+ [503, {}, ["Blocked"]]
52
+ end
53
+ end
54
+
55
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
56
+
57
+ assert_equal 503, last_response.status
58
+ assert_equal "Blocked", last_response.body
59
+ end
43
60
  end
@@ -20,7 +20,7 @@ describe "Customizing throttled response" do
20
20
 
21
21
  assert_equal 429, last_response.status
22
22
 
23
- Rack::Attack.throttled_response = lambda do |_env|
23
+ Rack::Attack.throttled_responder = lambda do |_req|
24
24
  [503, {}, ["Throttled"]]
25
25
  end
26
26
 
@@ -36,11 +36,11 @@ describe "Customizing throttled response" do
36
36
  match_data = nil
37
37
  match_discriminator = nil
38
38
 
39
- Rack::Attack.throttled_response = lambda do |env|
40
- matched = env['rack.attack.matched']
41
- match_type = env['rack.attack.match_type']
42
- match_data = env['rack.attack.match_data']
43
- match_discriminator = env['rack.attack.match_discriminator']
39
+ Rack::Attack.throttled_responder = lambda do |req|
40
+ matched = req.env['rack.attack.matched']
41
+ match_type = req.env['rack.attack.match_type']
42
+ match_data = req.env['rack.attack.match_data']
43
+ match_discriminator = req.env['rack.attack.match_discriminator']
44
44
 
45
45
  [429, {}, ["Throttled"]]
46
46
  end
@@ -58,4 +58,25 @@ describe "Customizing throttled response" do
58
58
  get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
59
59
  assert_equal 3, match_data[:count]
60
60
  end
61
+
62
+ it "supports old style" do
63
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
64
+
65
+ assert_equal 200, last_response.status
66
+
67
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
68
+
69
+ assert_equal 429, last_response.status
70
+
71
+ silence_warnings do
72
+ Rack::Attack.throttled_response = lambda do |_req|
73
+ [503, {}, ["Throttled"]]
74
+ end
75
+ end
76
+
77
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
78
+
79
+ assert_equal 503, last_response.status
80
+ assert_equal "Throttled", last_response.body
81
+ end
61
82
  end
@@ -2,7 +2,11 @@
2
2
 
3
3
  require_relative "../../spec_helper"
4
4
 
5
- if defined?(::Dalli)
5
+ should_run =
6
+ defined?(::Dalli) &&
7
+ Gem::Version.new(::Dalli::VERSION) < Gem::Version.new("3")
8
+
9
+ if should_run
6
10
  require_relative "../../support/cache_store_helper"
7
11
  require "active_support/cache/dalli_store"
8
12
  require "timecop"
@@ -64,15 +64,15 @@ describe 'Rack::Attack' do
64
64
  end
65
65
  end
66
66
 
67
- describe '#blocklisted_response' do
67
+ describe '#blocklisted_responder' do
68
68
  it 'should exist' do
69
- _(Rack::Attack.blocklisted_response).must_respond_to :call
69
+ _(Rack::Attack.blocklisted_responder).must_respond_to :call
70
70
  end
71
71
  end
72
72
 
73
- describe '#throttled_response' do
73
+ describe '#throttled_responder' do
74
74
  it 'should exist' do
75
- _(Rack::Attack.throttled_response).must_respond_to :call
75
+ _(Rack::Attack.throttled_responder).must_respond_to :call
76
76
  end
77
77
  end
78
78
  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.5.0
4
+ version: 6.6.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: 2021-02-07 00:00:00.000000000 Z
11
+ date: 2022-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -185,7 +185,7 @@ dependencies:
185
185
  version: '4.2'
186
186
  - - "<"
187
187
  - !ruby/object:Gem::Version
188
- version: '6.2'
188
+ version: '7.1'
189
189
  type: :development
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
@@ -195,13 +195,14 @@ dependencies:
195
195
  version: '4.2'
196
196
  - - "<"
197
197
  - !ruby/object:Gem::Version
198
- version: '6.2'
198
+ version: '7.1'
199
199
  description: A rack middleware for throttling and blocking abusive requests
200
200
  email: aaron@ktheory.com
201
201
  executables: []
202
202
  extensions: []
203
203
  extra_rdoc_files: []
204
204
  files:
205
+ - LICENSE
205
206
  - README.md
206
207
  - Rakefile
207
208
  - lib/rack/attack.rb
@@ -290,7 +291,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
291
  - !ruby/object:Gem::Version
291
292
  version: '0'
292
293
  requirements: []
293
- rubygems_version: 3.2.8
294
+ rubygems_version: 3.3.6
294
295
  signing_key:
295
296
  specification_version: 4
296
297
  summary: Block & throttle abusive requests