Commit graph

253 commits

Author SHA1 Message Date
Aaron Suggs
f5f08d56e5 More safelist/blocklist refactoring
- Add Rack::Attack namespace to deprecation warning.
- Add deprecated Rack::Attack.blacklisted_response attr methods.
2016-07-04 21:42:41 -04:00
Renée Hendricksen
e1a0c804e1 suggesting changing whitelist/blacklist language to less controversial safelist/blocklist language
add deprication warnings

fix the method signatures
2016-07-01 21:44:45 -04:00
Aaron Suggs
cf89457ced bump v4.4.1 2016-02-16 17:37:59 -05:00
Aaron Suggs
9d90610bbe Refactor StoreProxy to avoid autoloading MemCacheStore
In v4.4.0, checking `defined?(ActiveSupport::Cache::MemCacheStore)`
could trigger an error loading dalli, which isn’t needed.

This fixes that bug, and prevents similar bugs by checking
`store.class.to_s` rather than `defined?(klass) && store.is_a?(klass)`.

Writing an automated test to ensure that dalli is truly optional is
difficult, but I was able to recreate the dalli load error in v4.4.0 by
running:

    gem uninstall dalli
    ruby -Ilib -ractive_support/all -ractive_support/cache/redis_store
-rrack/attack -e 'p Rack::Attack::StoreProxy.build(Redis::Store.new)'

Fixes #163
2016-02-16 16:59:24 -05:00
Aaron Suggs
d8b9e2f111 v4.4.0
Update changelog
2016-02-10 15:05:43 -05:00
Vincent Boisard
585d1fd02c Revert "refactor unwieldy Rack::Attack::StoreProxy.build method"
This reverts commit 8d124d868e.
2016-01-12 11:45:44 +01:00
Vincent Boisard
c34bace773 style: remove extraneous whitespace 2016-01-07 22:45:11 +01:00
Vincent Boisard
8d124d868e refactor unwieldy Rack::Attack::StoreProxy.build method 2016-01-07 21:16:35 +01:00
Vincent Boisard
32df84df54 fix: check whether client class is defined before checking client itself 2015-12-29 10:19:13 +01:00
Vincent Boisard
297ef4a2ae Merge branch 'master' of github.com:kickstarter/rack-attack 2015-12-29 10:10:36 +01:00
Aaron Suggs
4ec58e36de Version v4.3.1 2015-12-18 11:43:14 -05:00
Aaron Suggs
76c2e31430 Normalize request paths when using Rails' ActionDispatch
The issue
---

When using rack-attack with a rails app, developers expect the request
path to be normalized. In particular, trailing slashes are stripped so
a request path "/login/" becomes "/login" by the time you're in
ActionController.

Since Rack::Attack runs before ActionDispatch, the request path is not
yet normalized. This can cause throttles and blacklists to not work as
expected.

E.g., a throttle:

    throttle('logins', ...) {|req| req.path == "/login" }

would not match a request to '/login/', though Rails would route
'/login/' to the same '/login' action.

The solution
---

This patch looks if ActionDispatch's request normalization is loaded,
and if so, uses it to normalize the path before processing throttles,
blacklists, etc.

If it's not loaded, the request path is not modified.

Credit
---
Thanks to Andres Riancho at Include Security for reporting this issue.
2015-12-18 11:12:11 -05:00
Vincent Boisard
d880bd88e0 fix: workaround MemCacheClient + MemCache backend by using a dedicated proxy 2015-12-16 16:57:54 +01:00
Vincent Boisard
faa0638719 fix: Do not attempt to process Memcache clients with DalliProxy 2015-12-08 18:55:06 +01:00
Vincent Boisard
397a7ce7b4 feature: support for ActiveSupport::MemCacheStore 2015-12-08 10:53:53 +01:00
Stan Hu
91947b83a4 Support the ability to reset Fail2Ban count and ban flag
Closes #113
2015-05-22 09:47:32 -04:00
Aaron Suggs
0ec73d956b Merge pull request #119 from stanhu/add-delete-interface
Support delete method for Redis
2015-04-16 14:11:58 -04:00
Aaron Suggs
1dd29f66b8 Update changelog for #118; bump to v4.3.0 2015-04-16 14:06:46 -04:00
Stan Hu
ff15447f3a Support delete method for Redis 2015-03-15 12:13:44 -07:00
Stan Hu
dc1b6bf687 Pass raw: true to prevent Ruby de/serialization. This is to make it possible
to implement something like:

```store.write(key, 0, :expires_in => expires_in)```

See #113
2015-03-15 07:18:18 -07:00
Aaron Suggs
f9b7721e59 bump version 4.2.0 2014-10-26 15:33:09 -04:00
Aaron Suggs
e7efe1cf5f Merge pull request #91 from gsamokovarov/call-responses
Invoke Rack:::{blacklisted,throttled}_response with #call
2014-10-02 14:25:42 -04:00
Aaron Suggs
a1cedbbc7e Merge pull request #93 from gsamokovarov/dont-rescue-nil
Avoid rescue nil in the default throttled response
2014-09-26 15:07:35 -04:00
Genadi Samokovarov
a161176142 Invoke {blacklisted,throttled}_response with #call
I have a response which is a class. While I can still have my class
implement `#[]`, it does look a bit off. On the other side, having
objects, responding to #call, that are not procs is pretty common.

So I propose to invoke the responses with `#call` to let users override
it with response objects, that respond to `#call` instead of `#[]`.
2014-09-25 23:21:02 +02:00
Genadi Samokovarov
f737dbb78c Avoid rescue nil in the default throttled response
It has a couple of cons:

1. If we slip a typo in the whole line, we won't easily catch it.  Can
   you guys spot the problem problem in the following line? Chasing such
   issues is quite tricky.

```ruby
retry_after = evn['rack.attack.match_data'][:period] rescue nil
```

2. Throwing and catching an exception is quite slower than a new hash
   allocation, so there is a speed benefit too.

We are guaranteed from Rack that env is a `Hash`, so we can even use
`Hash#fetch`.

```ruby
retry_after = env.fetch('rack.attack.match_data', {})[:period]
```

This reads better, but always allocates the default value hash, when the
other version allocates it only when needed. If you prefer `Hash#fetch`,
I'm fine with that, as long as we avoid `rescue nil`.
2014-09-25 18:35:53 +02:00
Genadi Samokovarov
d9a5587676 Allow throttle period option to be a proc
I need to filter requests on a period I need to get dynamically out of
information I have in the requests. Currently, I can work out the limit,
as it can be a `Proc`, however I can't do that with the period.

This PR adds support for that. Tried to do it in a way that doesn't
brake backwards compatibility, as periods are coerced to numbers during
`Rack::Throttle` initialization.
2014-09-19 19:32:39 +02:00
Aaron Suggs
1db5a00431 version 4.1.1 2014-09-08 21:34:28 -04:00
Aaron Suggs
074e8e5aa4 Add 1 second buffer to expiry to correct throttles
Fixes #69.

There was a race condition when `Time.now.to_i` changes between when
`epoch_time` is computed in line 18, and the cache request is made (and
the `key` is expired).

I.e., a throttle check starts at t0, but doesn’t reach the cache until
t1, the cache will have expired the throttle count. The request will
likely be allowed, even if the request exceeded the limit.

This has the effect of keeping keys in cache about 1 second longer than
strictly necessary. But the extra cache space seems like a good
trade-off for correct throttling.
2014-09-02 14:30:57 -04:00
Aaron Suggs
7820986d9c Merge pull request #74 from zmillman/readme-request
Improve documentation of Rack::Attack::Request
2014-08-01 14:43:53 -04:00
Zach Millman
5c78f84be2 Improve documentation of Rack::Attack::Request
https://github.com/kickstarter/rack-attack/issues/73
2014-06-17 11:37:25 -07:00
Aaron Suggs
1a3cddb468 Prep for v4.1.0 2014-05-22 13:59:26 -04:00
Aaron Suggs
105c3ba575 Merge pull request #67 from chiliburger/track_only
Limit and period options for track
2014-05-22 13:55:54 -04:00
Paul Coates
e8d98a7ad3 Changed track checker to track filter. Made track filter tests more clear. 2014-05-22 10:11:23 -07:00
Aaron Suggs
6f7bd66dfa Default responses: add Content-Type header
Fixes #68
2014-05-21 18:35:28 -04:00
Paul Coates
1ebe1c3517 Added limit and period options to track. Delegates [] to Throttle if they are present otherwise Check. 2014-05-19 11:11:01 -07:00
Aaron Suggs
f9eabed6d4 Rack::Attack.clear! resets tracks
Fixes flaky tests like
https://travis-ci.org/kickstarter/rack-attack/builds/25438931
2014-05-18 20:46:11 -04:00
Aaron Suggs
0e599a4dd6 version 4.0.1 2014-05-14 13:37:30 -04:00
blahed
97dce48bfc add throttle discriminator to rack env 2014-05-01 22:20:13 -04:00
Aaron Suggs
430672d8f4 Update changelog for v4.0.0 2014-04-28 15:45:13 -04:00
hakanensari
5d72c6e5f9 Move individual proxy classes to separate files 2014-04-15 16:19:43 +01:00
hakanensari
f0a53f474e Stub #with on delegator 2014-04-09 13:15:00 +01:00
hakanensari
937cd3ca20 Merge branch 'master' into patch-3 2014-04-09 12:17:10 +01:00
hakanensari
1c0bc3da4d Merge branch 'patch-2' into patch-3
Conflicts:
	lib/rack/attack/store_proxy.rb
2014-04-09 12:16:16 +01:00
Aaron Suggs
66231dc5b2 v3.1.0 2014-04-04 16:16:31 -04:00
Tristan Dunn
16f1cfc578 Add a custom request class to allow for helper methods.
Fixes #58.
2014-04-04 14:41:59 -05:00
Aaron Suggs
ea09a49538 Merge pull request #54 from stevehodgkiss/dont_override_new_and_return_a_class
Rack::Attack.new should return an instance of a class, not the Rack::Attack constant
2014-04-03 22:37:05 -04:00
Steve Hodgkiss
93421efa5a Tidy up defaults. We don't need to use ||= because this runs when the class gets loaded, and we won't have user supplied defaults yet. 2014-04-02 17:12:28 +11:00
Steve Hodgkiss
332dd4ff9e Delegate to class methods with forwardable 2014-04-02 17:08:46 +11:00
hakanensari
92be2791ab Handle older Dalli clients 2014-04-01 12:23:10 +01:00
hakanensari
128c5aa9bf Support a Dalli Connection Pool 2014-04-01 12:10:32 +01:00
hakanensari
adab844784 Support older dalli client versions 2014-04-01 11:21:14 +01:00
Steve Hodgkiss
c3a077442a Make Rack::Attack a class and Rack::Attack.new return an instance of that class, rather than Rack::Attack. 2014-03-28 14:53:51 +11:00
hakanensari
a7ec48fb44 Implement Proxy for Dalli
kickstarter/rack-attack#52
2014-03-26 21:54:12 +00:00
Aaron Suggs
7c6cead69c Version 3.0.0; update changelog 2014-03-15 08:01:55 -04:00
Will Kimeria
87f628d0c1 If redis client throws exception, don't raise it
For throttling, when the redis client throws an exception, the request
ends up getting rate limited. Modify this to be similar to how
ActiveSupport.MemCacheStore functions (the read, write and increment
methods do not raise exceptions)
2014-03-14 11:50:59 -07:00
Carsten Zimmermann
1095f85242 Change response body to 'Forbidden' 2014-02-06 23:29:44 +01:00
Carsten Zimmermann
97a43f7e66 Return 403 Forbidden instead of 401
401 Unauthorized suggests that the requests can be
retried with appropriate credentials. 403 explicitly
states that the request should not be repeated.

See #41
2014-02-06 21:32:51 +01:00
Jordan Moncharmont
273e045f10 fix edge case, if maxretry is 1, let them get 1 request in 2013-09-27 17:35:01 -07:00
Jordan Moncharmont
ef59c5182a Allow2Ban
An alternate to fail2ban that allows clients until they hit the
thresholds, then blocks them.  Think of it like a throttle where you can
block for more than one period.
2013-09-27 17:18:52 -07:00
Aaron Suggs
1d367f5acd version 2.3.0, update changelog, copy tweaks 2013-08-20 11:39:44 -04:00
Pedro Nascimento
ab6d7b239d Allow limit option to be a proc.
This allows you to do stuff like:
`req.env["USER"] == "god" ? 1000 : 1`
2013-08-19 19:47:48 -03:00
Aaron Suggs
98eec24a8c Update changelog, version 2.2.1 2013-08-05 21:14:16 -04:00
Alex Volkovitsky & Sachin Maharjan
cfbee2c552 Use correct HTTP status codes for blackist and throttle 2013-06-28 10:55:28 -07:00
Aaron Suggs
9388e98eb0 version 2.2.0 2013-06-20 11:05:00 -04:00
Aaron Suggs
24143dd195 Cleanup whitespace 2013-06-20 10:19:56 -04:00
madlep
2819e0d7a4 collapse fail2ban name/discriminator into one argument 2013-06-17 08:50:39 +10:00
madlep
94a304b815 reorder logic to not repeatedly extend ban after more failed requests 2013-06-14 12:49:53 +10:00
madlep
3f1c98a868 Fail2Ban helper
based on gist from @ktheory https://gist.github.com/ktheory/5723534

Modified slightly to use fail2ban `filter` terminology to simplify
Rack::Attack initializer configuration (only one block is requred for
this approach instead of 2)
2013-06-12 15:51:13 +10:00
madlep
6c259ea9be delegate Redis custom logic to StoreProxy
this removes ugly `if redis blah` code from cache
2013-06-12 15:03:39 +10:00
madlep
22fc386bad add read/write methods to cache 2013-06-12 15:03:24 +10:00
Aaron Suggs
d1cf2a2eea bump to version 2.1.1 2013-05-16 14:24:41 -04:00
Han Chang
2a91eb6c55 Fix #14 2013-05-10 22:08:31 +00:00
Aaron Suggs
22f051fa2d Merge pull request #10 from vipulnsward/mandatory_options
extract mandatory options constant
2013-05-03 07:41:02 -07:00
Vipul A M
7f3a24022b extract mandatory options constant 2013-05-03 09:25:43 +05:30
Vipul A M
709a2331c0 Remove unused var 2013-05-03 09:19:09 +05:30
Vipul A M
d3a9667474 Fix typos 2013-05-03 00:55:23 +05:30
Aaron Suggs
917d47758e Add newlines to default responses 2013-03-04 21:06:15 -05:00
Aaron Suggs
1c01e6097c bump to version 2.1.0 2013-02-25 22:39:11 -05:00
Aaron Suggs
cf508e1d18 Support RedisStore as cache store
Add tests for different cache stores
2013-02-25 12:09:59 -05:00
Aaron Suggs
27a13f6971 Clarify algorithm 2013-01-17 12:06:16 -05:00
Aaron Suggs
0ca7b8cfac whitespace 2013-01-17 12:06:16 -05:00
Aaron Suggs
3bcb453464 Version 2.0.0 2013-01-11 14:41:27 -05:00
Aaron Suggs
b577dae1c0 use each_value instead of each 2013-01-11 14:32:20 -05:00
Aaron Suggs
80367e1e4a Add Rack::Attack.track.
track will fire notifications, but not alter request processing
2013-01-10 19:02:49 -05:00
Aaron Suggs
eeb238b78d Use autoload instead of require 2013-01-10 18:36:31 -05:00
Aaron Suggs
5b864ca3d1 version bump 1.3.2 2012-08-15 18:16:12 -04:00
Aaron Suggs
f7a1eac521 Cache key time must be a fixnum 2012-08-15 18:16:12 -04:00
Aaron Suggs
853c9ceef3 Set :expires_in on throttle cache counters
Should reduce memcached evictions
2012-08-09 11:05:30 -04:00
Aaron Suggs
e7aa5f4abe Use rotating cache keys for throttle (instead of expiring)
Throttles use a cache key with a timestamp (Time.now.to_i/period), so a
new cache key is used for each period.

No longer set an explicit expiry on each cache key (though it may
inherit a default expiry from the cache store).

Also, set env['rack.attack.throttle_data'] with info about incremented
(but not necessarily exceeded) throttles.
2012-08-08 14:59:42 -04:00
Aaron Suggs
6784f21612 Better cache interface 2012-08-06 14:16:08 -04:00
Aaron Suggs
9c4dccac48 Make cache & notifier attr_accessors
Easier config for non-rails apps
2012-08-06 12:17:31 -04:00
Aaron Suggs
d50e779cdc version 1.0.0 2012-08-02 12:15:40 -04:00
Aaron Suggs
8e59e84e00 Response header values must be strings 2012-08-02 12:15:16 -04:00
Aaron Suggs
ccdc1f993a Change instrumentation API for simpler notifications 2012-07-30 15:44:22 -04:00
Aaron Suggs
61a046a203 Cleanup instrumentation interface 2012-07-30 09:34:30 -04:00
Aaron Suggs
cf49b00c00 DRY up initial values 2012-07-28 22:09:56 -04:00
Aaron Suggs
c90a0182eb Allow custom responses based on env 2012-07-28 19:51:24 -04:00
Aaron Suggs
dc2e402812 Initial working version 2012-07-27 17:40:11 -04:00
Aaron Suggs
e166e87fb9 Add throttle support 2012-07-27 17:22:49 -04:00
Aaron Suggs
c22c33f9ec add rake 2012-07-27 09:56:15 -04:00
Aaron Suggs
9284a08cc3 Whitelists support 2012-07-26 17:29:09 -04:00
Aaron Suggs
7fab5df499 WIP 2012-07-24 19:59:46 -04:00
Aaron Suggs
140ea86b7c Initial commit 2012-07-24 19:40:55 -04:00