rack-attack 4.3.0 → 4.3.1

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
  SHA1:
3
- metadata.gz: da0016c3e3d7fee696a96f8f1e3a493b0b197518
4
- data.tar.gz: 6b337c7d2ed9c48dbfd4cfc031ab6157fbceda3d
3
+ metadata.gz: 62911565ba358aadd130a8edf862d1f3ca57786d
4
+ data.tar.gz: 55876d8afb3bed309bb09a5b1fae357c8d5cdf10
5
5
  SHA512:
6
- metadata.gz: 1f84ef0262ee5f64ed98d745bedf49f7e8ef38693a3bc8e0eddb643dc7165e881ee11642944cf75d52769e13f6da934be69bf3156c6945e938caa139bf886252
7
- data.tar.gz: b952d3bd6061eaf8c7b5172c0b6620d4e3797d383c7a00d9d6d80eef78d470ba3ce8dbb1c57f801f3685164f7076a587236fc5bc3550b433c3771bddbfe589ef
6
+ metadata.gz: b54245dad4b5101ce8364da45654d650bfe86c2f4e3c85d48e3923b7ca8a31ad5ec61e3938745dedefba3fd117447e522a4207145b086eccf86bf14ba1696643
7
+ data.tar.gz: 57063639a9c9d6e3884b1a89cbfce044fefebe7dcb4a95f1e025e260db75490a05447d4e7294060aa55531b55d567b9763101debb2119a690c8760b0b94787ec
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  Rack::Attack is a rack middleware to protect your web app from bad clients.
5
5
  It allows *whitelisting*, *blacklisting*, *throttling*, and *tracking* based on arbitrary properties of the request.
6
6
 
7
- Throttle state is stored in a configurable cache (e.g. `Rails.cache`), presumably backed by memcached or redis ([at least gem v3.0.0](https://rubygems.org/gems/redis)).
7
+ Throttle and fail2ban state is stored in a configurable cache (e.g. `Rails.cache`), presumably backed by memcached or redis ([at least gem v3.0.0](https://rubygems.org/gems/redis)).
8
8
 
9
9
  See the [Backing & Hacking blog post](http://www.kickstarter.com/backing-and-hacking/rack-attack-protection-from-abusive-clients) introducing Rack::Attack.
10
10
 
@@ -47,13 +47,13 @@ end
47
47
  *Tip:* The example in the wiki is a great way to get started:
48
48
  [Example Configuration](https://github.com/kickstarter/rack-attack/wiki/Example-Configuration)
49
49
 
50
- Optionally configure the cache store for throttling:
50
+ Optionally configure the cache store for throttling or fail2ban filtering:
51
51
 
52
52
  ```ruby
53
53
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new # defaults to Rails.cache
54
54
  ```
55
55
 
56
- Note that `Rack::Attack.cache` is only used for throttling; not blacklisting & whitelisting. Your cache store must implement `increment` and `write` like [ActiveSupport::Cache::Store](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html).
56
+ Note that `Rack::Attack.cache` is only used for throttling and fail2ban filtering; not blacklisting & whitelisting. Your cache store must implement `increment` and `write` like [ActiveSupport::Cache::Store](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html).
57
57
 
58
58
  ## How it works
59
59
 
@@ -104,7 +104,7 @@ A [Rack::Request](http://www.rubydoc.info/gems/rack/Rack/Request) object is pass
104
104
  # (blacklist & throttles are skipped)
105
105
  Rack::Attack.whitelist('allow from localhost') do |req|
106
106
  # Requests are allowed if the return value is truthy
107
- '127.0.0.1' == req.ip
107
+ '127.0.0.1' == req.ip || '::1' == req.ip
108
108
  end
109
109
  ```
110
110
 
@@ -128,21 +128,27 @@ end
128
128
  `Fail2Ban.filter` can be used within a blacklist to block all requests from misbehaving clients.
129
129
  This pattern is inspired by [fail2ban](http://www.fail2ban.org/wiki/index.php/Main_Page).
130
130
  See the [fail2ban documentation](http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jail_Options) for more details on
131
- how the parameters work.
131
+ how the parameters work. For multiple filters, be sure to put each filter in a separate blacklist and use a unique discriminator for each fail2ban filter.
132
132
 
133
133
  ```ruby
134
- # Block requests containing '/etc/password' in the params.
134
+ # Block suspicious requests for '/etc/password' or wordpress specific paths.
135
135
  # After 3 blocked requests in 10 minutes, block all requests from that IP for 5 minutes.
136
136
  Rack::Attack.blacklist('fail2ban pentesters') do |req|
137
137
  # `filter` returns truthy value if request fails, or if it's from a previously banned IP
138
138
  # so the request is blocked
139
- Rack::Attack::Fail2Ban.filter(req.ip, :maxretry => 3, :findtime => 10.minutes, :bantime => 5.minutes) do
140
- # The count for the IP is incremented if the return value is truthy.
141
- CGI.unescape(req.query_string) =~ %r{/etc/passwd}
139
+ Rack::Attack::Fail2Ban.filter("pentesters-#{req.ip}", :maxretry => 3, :findtime => 10.minutes, :bantime => 5.minutes) do
140
+ # The count for the IP is incremented if the return value is truthy
141
+ CGI.unescape(req.query_string) =~ %r{/etc/passwd} ||
142
+ req.path.include?('/etc/passwd') ||
143
+ req.path.include?('wp-admin') ||
144
+ req.path.include?('wp-login')
145
+
142
146
  end
143
147
  end
144
148
  ```
145
149
 
150
+ Note that `Fail2Ban` filters are not automatically scoped to the blacklist, so when using multiple filters in an application the scoping must be added to the discriminator e.g. `"pentest:#{req.ip}"`.
151
+
146
152
  #### Allow2Ban
147
153
  `Allow2Ban.filter` works the same way as the `Fail2Ban.filter` except that it *allows* requests from misbehaving
148
154
  clients until such time as they reach maxretry at which they are cut off as per normal.
@@ -283,6 +289,12 @@ It is impractical if not impossible to block abusive clients completely.
283
289
  Rack::Attack aims to let developers quickly mitigate abusive requests and rely
284
290
  less on short-term, one-off hacks to block a particular attack.
285
291
 
292
+ ## Contributing
293
+
294
+ Pull requests and issues are greatly appreciated. This project is intended to be
295
+ a safe, welcoming space for collaboration, and contributors are expected to
296
+ adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).
297
+
286
298
  ## Mailing list
287
299
 
288
300
  New releases of Rack::Attack are announced on
@@ -3,6 +3,7 @@ require 'forwardable'
3
3
 
4
4
  class Rack::Attack
5
5
  autoload :Cache, 'rack/attack/cache'
6
+ autoload :PathNormalizer, 'rack/attack/path_normalizer'
6
7
  autoload :Check, 'rack/attack/check'
7
8
  autoload :Throttle, 'rack/attack/throttle'
8
9
  autoload :Whitelist, 'rack/attack/whitelist'
@@ -91,6 +92,7 @@ class Rack::Attack
91
92
  end
92
93
 
93
94
  def call(env)
95
+ env['PATH_INFO'] = PathNormalizer.normalize_path(env['PATH_INFO'])
94
96
  req = Rack::Attack::Request.new(env)
95
97
 
96
98
  if whitelisted?(req)
@@ -0,0 +1,27 @@
1
+ class Rack::Attack
2
+
3
+ # When using Rack::Attack with a Rails app, developers expect the request path
4
+ # to be normalized. In particular, trailing slashes are stripped.
5
+ # (See http://git.io/v0rrR for implementation.)
6
+ #
7
+ # Look for an ActionDispatch utility class that Rails folks would expect
8
+ # to normalize request paths. If unavailable, use a fallback class that
9
+ # doesn't normalize the path (as a non-Rails rack app developer expects).
10
+
11
+ module FallbackPathNormalizer
12
+ def self.normalize_path(path)
13
+ path
14
+ end
15
+ end
16
+
17
+ PathNormalizer = if defined?(::ActionDispatch::Journey::Router::Utils)
18
+ # For Rails 4+ apps
19
+ ::ActionDispatch::Journey::Router::Utils
20
+ elsif defined?(::Journey::Router::Utils)
21
+ # for Rails 3.2
22
+ ::Journey::Router::Utils
23
+ else
24
+ FallbackPathNormalizer
25
+ end
26
+
27
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Attack
3
- VERSION = '4.3.0'
3
+ VERSION = '4.3.1'
4
4
  end
5
5
  end
@@ -0,0 +1,17 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Rack::Attack::PathNormalizer do
4
+ subject { Rack::Attack::PathNormalizer }
5
+
6
+ it 'should have a normalize_path method' do
7
+ subject.normalize_path('/foo').must_equal '/foo'
8
+ end
9
+
10
+ describe 'FallbackNormalizer' do
11
+ subject { Rack::Attack::FallbackPathNormalizer }
12
+
13
+ it '#normalize_path does not change the path' do
14
+ subject.normalize_path('').must_equal ''
15
+ end
16
+ end
17
+ end
@@ -3,6 +3,17 @@ require_relative 'spec_helper'
3
3
  describe 'Rack::Attack' do
4
4
  allow_ok_requests
5
5
 
6
+ describe 'normalizing paths' do
7
+ before do
8
+ Rack::Attack.blacklist("banned_path") {|req| req.path == '/foo' }
9
+ end
10
+
11
+ it 'blocks requests with trailing slash' do
12
+ get '/foo/'
13
+ last_response.status.must_equal 403
14
+ end
15
+ end
16
+
6
17
  describe 'blacklist' do
7
18
  before do
8
19
  @bad_ip = '1.2.3.4'
@@ -5,12 +5,17 @@ require "minitest/autorun"
5
5
  require "minitest/pride"
6
6
  require "rack/test"
7
7
  require 'active_support'
8
+ require 'action_dispatch'
9
+
10
+ # Load Journey for Rails 3.2
11
+ require 'journey' if ActionPack::VERSION::MAJOR == 3
12
+
8
13
  require "rack/attack"
9
14
 
10
15
  begin
11
- require 'debugger'
16
+ require 'pry'
12
17
  rescue LoadError
13
- #nothing to do here
18
+ #nothing to do here
14
19
  end
15
20
 
16
21
  class MiniTest::Spec
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.3.0
4
+ version: 4.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: 2015-05-22 00:00:00.000000000 Z
11
+ date: 2015-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: actionpack
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 3.0.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 3.0.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: redis-activesupport
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,7 @@ files:
150
164
  - lib/rack/attack/cache.rb
151
165
  - lib/rack/attack/check.rb
152
166
  - lib/rack/attack/fail2ban.rb
167
+ - lib/rack/attack/path_normalizer.rb
153
168
  - lib/rack/attack/request.rb
154
169
  - lib/rack/attack/store_proxy.rb
155
170
  - lib/rack/attack/store_proxy/dalli_proxy.rb
@@ -163,6 +178,7 @@ files:
163
178
  - spec/integration/offline_spec.rb
164
179
  - spec/integration/rack_attack_cache_spec.rb
165
180
  - spec/rack_attack_dalli_proxy_spec.rb
181
+ - spec/rack_attack_path_normalizer_spec.rb
166
182
  - spec/rack_attack_request_spec.rb
167
183
  - spec/rack_attack_spec.rb
168
184
  - spec/rack_attack_throttle_spec.rb
@@ -181,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
181
197
  requirements:
182
198
  - - ">="
183
199
  - !ruby/object:Gem::Version
184
- version: 1.9.2
200
+ version: 2.0.0
185
201
  required_rubygems_version: !ruby/object:Gem::Requirement
186
202
  requirements:
187
203
  - - ">="
@@ -189,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
205
  version: '0'
190
206
  requirements: []
191
207
  rubyforge_project:
192
- rubygems_version: 2.4.5
208
+ rubygems_version: 2.4.5.1
193
209
  signing_key:
194
210
  specification_version: 4
195
211
  summary: Block & throttle abusive requests
@@ -199,6 +215,7 @@ test_files:
199
215
  - spec/integration/offline_spec.rb
200
216
  - spec/integration/rack_attack_cache_spec.rb
201
217
  - spec/rack_attack_dalli_proxy_spec.rb
218
+ - spec/rack_attack_path_normalizer_spec.rb
202
219
  - spec/rack_attack_request_spec.rb
203
220
  - spec/rack_attack_spec.rb
204
221
  - spec/rack_attack_throttle_spec.rb