rack-attack 4.3.0 → 4.3.1
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 +21 -9
- data/lib/rack/attack.rb +2 -0
- data/lib/rack/attack/path_normalizer.rb +27 -0
- data/lib/rack/attack/version.rb +1 -1
- data/spec/rack_attack_path_normalizer_spec.rb +17 -0
- data/spec/rack_attack_spec.rb +11 -0
- data/spec/spec_helper.rb +7 -2
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62911565ba358aadd130a8edf862d1f3ca57786d
|
4
|
+
data.tar.gz: 55876d8afb3bed309bb09a5b1fae357c8d5cdf10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
data/lib/rack/attack.rb
CHANGED
@@ -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
|
data/lib/rack/attack/version.rb
CHANGED
@@ -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
|
data/spec/rack_attack_spec.rb
CHANGED
@@ -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'
|
data/spec/spec_helper.rb
CHANGED
@@ -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 '
|
16
|
+
require 'pry'
|
12
17
|
rescue LoadError
|
13
|
-
|
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.
|
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-
|
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:
|
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
|