rack-attack 1.3.1 → 1.3.2
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.
Potentially problematic release.
This version of rack-attack might be problematic. Click here for more details.
- data/README.md +15 -13
- data/lib/rack/attack/cache.rb +1 -1
- data/lib/rack/attack/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Rack::Attack!!!
|
2
|
-
*A DSL for blocking &
|
2
|
+
*A DSL for blocking & throttling abusive clients*
|
3
3
|
|
4
4
|
Rack::Attack is a rack middleware to protect your web app from bad clients.
|
5
|
-
It allows *whitelisting*, *blacklisting*, and *
|
5
|
+
It allows *whitelisting*, *blacklisting*, and *throttling* based on arbitrary properties of the request.
|
6
6
|
|
7
|
-
|
7
|
+
Throttle state is stored in a configurable cache (e.g. `Rails.cache`), presumably backed by memcached.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -28,7 +28,7 @@ Optionally configure the cache store for throttling:
|
|
28
28
|
|
29
29
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new # defaults to Rails.cache
|
30
30
|
|
31
|
-
Note that `Rack::Attack.cache` is only used for throttling
|
31
|
+
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).
|
32
32
|
|
33
33
|
## How it works
|
34
34
|
|
@@ -40,8 +40,8 @@ The Rack::Attack middleware compares each request against *whitelists*, *blackli
|
|
40
40
|
|
41
41
|
## Usage
|
42
42
|
|
43
|
-
Define blacklists, throttles, and whitelists.
|
44
|
-
|
43
|
+
Define blacklists, throttles, and whitelists as blocks that return truthy of falsy values.
|
44
|
+
A [Rack::Request](http://rack.rubyforge.org/doc/classes/Rack/Request.html) object is passed to the block (named 'req' in the examples).
|
45
45
|
|
46
46
|
### Blacklists
|
47
47
|
|
@@ -53,23 +53,25 @@ Note that `req` is a [Rack::Request](http://rack.rubyforge.org/doc/classes/Rack/
|
|
53
53
|
|
54
54
|
# Block logins from a bad user agent
|
55
55
|
Rack::Attack.blacklist('block bad UA logins') do |req|
|
56
|
-
req.
|
56
|
+
req.path == '/login' && req.post? && req.user_agent == 'BadUA'
|
57
57
|
end
|
58
58
|
|
59
59
|
### Throttles
|
60
60
|
|
61
61
|
# Throttle requests to 5 requests per second per ip
|
62
62
|
Rack::Attack.throttle('req/ip', :limit => 5, :period => 1.second) do |req|
|
63
|
-
# If the return value is truthy, the cache key for
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
63
|
+
# If the return value is truthy, the cache key for the return value
|
64
|
+
# is incremented and compared with the limit. In this case:
|
65
|
+
# "rack::attack:#{Time.now.to_i/1.second}:req/ip:#{req.ip}"
|
66
|
+
#
|
67
|
+
# If falsy, the cache key is neither incremented nor checked.
|
68
|
+
|
67
69
|
req.ip
|
68
70
|
end
|
69
71
|
|
70
72
|
# Throttle login attempts for a given email parameter to 6 reqs/minute
|
71
73
|
Rack::Attack.throttle('logins/email', :limit => 6, :period => 60.seconds) do |req|
|
72
|
-
|
74
|
+
request.path == '/login' && req.post? && req.params['email']
|
73
75
|
end
|
74
76
|
|
75
77
|
### Whitelists
|
@@ -124,7 +126,7 @@ It is impractical if not impossible to block abusive clients completely.
|
|
124
126
|
Rack::Attack aims to let developers quickly mitigate abusive requests and rely
|
125
127
|
less on short-term, one-off hacks to block a particular attack.
|
126
128
|
|
127
|
-
Rack::Attack complements
|
129
|
+
Rack::Attack complements tools like iptables and nginx's [limit_zone module](http://wiki.nginx.org/HttpLimitZoneModule).
|
128
130
|
|
129
131
|
[](http://travis-ci.org/ktheory/rack-attack)
|
130
132
|
|
data/lib/rack/attack/cache.rb
CHANGED
@@ -11,7 +11,7 @@ module Rack
|
|
11
11
|
def count(unprefixed_key, period)
|
12
12
|
epoch_time = Time.now.to_i
|
13
13
|
expires_in = period - (epoch_time % period)
|
14
|
-
key = "#{prefix}:#{epoch_time/period}:#{unprefixed_key}"
|
14
|
+
key = "#{prefix}:#{(epoch_time/period).to_i}:#{unprefixed_key}"
|
15
15
|
result = store.increment(key, 1, :expires_in => expires_in)
|
16
16
|
# NB: Some stores return nil when incrementing uninitialized values
|
17
17
|
if result.nil?
|
data/lib/rack/attack/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-attack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|