mirror of
https://github.com/samsonjs/rack-attack.git
synced 2026-04-26 14:57:47 +00:00
Merge branch 'master' of github.com:kickstarter/rack-attack
This commit is contained in:
commit
297ef4a2ae
18 changed files with 140 additions and 6 deletions
|
|
@ -1,13 +1,21 @@
|
||||||
appraise 'activesupport3.2' do
|
appraise 'activesupport3.2' do
|
||||||
gem 'activesupport', '~> 3.2.0'
|
gem 'activesupport', '~> 3.2.0'
|
||||||
|
gem 'actionpack', '~> 3.2.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'activesupport4.0' do
|
appraise 'activesupport4.0' do
|
||||||
gem 'activesupport', '~> 4.0.0'
|
gem 'activesupport', '~> 4.0.0'
|
||||||
|
gem 'actionpack', '~> 4.0.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'activesupport4.1' do
|
appraise 'activesupport4.1' do
|
||||||
gem 'activesupport', '~> 4.1.0'
|
gem 'activesupport', '~> 4.1.0'
|
||||||
|
gem 'actionpack', '~> 4.1.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
appraise 'activesupport4.2' do
|
||||||
|
gem 'activesupport', '~> 4.2.0'
|
||||||
|
gem 'actionpack', '~> 4.2.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
appraise 'dalli1.1' do
|
appraise 'dalli1.1' do
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
# Changlog
|
# Changlog
|
||||||
|
|
||||||
## master (unreleased)
|
## master (unreleased)
|
||||||
|
|
||||||
|
## v4.3.1 - 18 Dec 2015
|
||||||
|
- SECURITY FIX: Normalize request paths when using ActionDispatch. Thanks
|
||||||
|
Andres Riancho at @includesecurity for reporting it.
|
||||||
- Remove support for ruby 1.9.x
|
- Remove support for ruby 1.9.x
|
||||||
|
- Add Code of Conduct
|
||||||
|
- Several documentation and testing improvements
|
||||||
|
|
||||||
## v4.3.0 - 22 May 2015
|
## v4.3.0 - 22 May 2015
|
||||||
|
|
||||||
|
|
|
||||||
9
Gemfile
9
Gemfile
|
|
@ -1,4 +1,9 @@
|
||||||
source "https://rubygems.org"
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
#gem 'debugger', platform: 'ruby'
|
group :development do
|
||||||
|
gem 'pry'
|
||||||
|
gem 'guard' # NB: this is necessary in newer versions
|
||||||
|
gem 'guard-minitest'
|
||||||
|
end
|
||||||
|
|
|
||||||
10
Guardfile
Normal file
10
Guardfile
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# A sample Guardfile
|
||||||
|
# More info at https://github.com/guard/guard#readme
|
||||||
|
|
||||||
|
guard :minitest do
|
||||||
|
# with Minitest::Spec
|
||||||
|
watch(%r{^spec/(.*)_spec\.rb$})
|
||||||
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
|
watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -147,6 +147,8 @@ Rack::Attack.blacklist('fail2ban pentesters') do |req|
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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}"`.
|
||||||
|
|
||||||
#### Allow2Ban
|
#### Allow2Ban
|
||||||
`Allow2Ban.filter` works the same way as the `Fail2Ban.filter` except that it *allows* requests from misbehaving
|
`Allow2Ban.filter` works the same way as the `Fail2Ban.filter` except that it *allows* requests from misbehaving
|
||||||
clients until such time as they reach maxretry at which they are cut off as per normal.
|
clients until such time as they reach maxretry at which they are cut off as per normal.
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,12 @@ source "https://rubygems.org"
|
||||||
|
|
||||||
gem "activesupport", "~> 3.2.0"
|
gem "activesupport", "~> 3.2.0"
|
||||||
gem "memcache-client"
|
gem "memcache-client"
|
||||||
|
gem "actionpack", "~> 3.2.0"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,12 @@
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
gem "activesupport", "~> 4.0.0"
|
gem "activesupport", "~> 4.0.0"
|
||||||
|
gem "actionpack", "~> 4.0.0"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,12 @@
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
gem "activesupport", "~> 4.1.0"
|
gem "activesupport", "~> 4.1.0"
|
||||||
|
gem "actionpack", "~> 4.1.0"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
gem "activesupport", "~> 4.2.1"
|
gem "activesupport", "~> 4.2.0"
|
||||||
|
gem "actionpack", "~> 4.2.0"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,10 @@ source "https://rubygems.org"
|
||||||
|
|
||||||
gem "dalli", "1.1.5"
|
gem "dalli", "1.1.5"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,10 @@ source "https://rubygems.org"
|
||||||
|
|
||||||
gem "dalli", "~> 2.0"
|
gem "dalli", "~> 2.0"
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem "pry"
|
||||||
|
gem "guard"
|
||||||
|
gem "guard-minitest"
|
||||||
|
end
|
||||||
|
|
||||||
gemspec :path => "../"
|
gemspec :path => "../"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ require 'forwardable'
|
||||||
|
|
||||||
class Rack::Attack
|
class Rack::Attack
|
||||||
autoload :Cache, 'rack/attack/cache'
|
autoload :Cache, 'rack/attack/cache'
|
||||||
|
autoload :PathNormalizer, 'rack/attack/path_normalizer'
|
||||||
autoload :Check, 'rack/attack/check'
|
autoload :Check, 'rack/attack/check'
|
||||||
autoload :Throttle, 'rack/attack/throttle'
|
autoload :Throttle, 'rack/attack/throttle'
|
||||||
autoload :Whitelist, 'rack/attack/whitelist'
|
autoload :Whitelist, 'rack/attack/whitelist'
|
||||||
|
|
@ -92,6 +93,7 @@ class Rack::Attack
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
|
env['PATH_INFO'] = PathNormalizer.normalize_path(env['PATH_INFO'])
|
||||||
req = Rack::Attack::Request.new(env)
|
req = Rack::Attack::Request.new(env)
|
||||||
|
|
||||||
if whitelisted?(req)
|
if whitelisted?(req)
|
||||||
|
|
|
||||||
27
lib/rack/attack/path_normalizer.rb
Normal file
27
lib/rack/attack/path_normalizer.rb
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
class Rack::Attack
|
||||||
|
|
||||||
|
# When using Rack::Attack with a Rails app, developers expect the request path
|
||||||
|
# to be normalized. In particular, trailing slashes are stripped.
|
||||||
|
# (See http://git.io/v0rrR for implementation.)
|
||||||
|
#
|
||||||
|
# Look for an ActionDispatch utility class that Rails folks would expect
|
||||||
|
# to normalize request paths. If unavailable, use a fallback class that
|
||||||
|
# doesn't normalize the path (as a non-Rails rack app developer expects).
|
||||||
|
|
||||||
|
module FallbackPathNormalizer
|
||||||
|
def self.normalize_path(path)
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
PathNormalizer = if defined?(::ActionDispatch::Journey::Router::Utils)
|
||||||
|
# For Rails 4+ apps
|
||||||
|
::ActionDispatch::Journey::Router::Utils
|
||||||
|
elsif defined?(::Journey::Router::Utils)
|
||||||
|
# for Rails 3.2
|
||||||
|
::Journey::Router::Utils
|
||||||
|
else
|
||||||
|
FallbackPathNormalizer
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
module Rack
|
module Rack
|
||||||
class Attack
|
class Attack
|
||||||
VERSION = '4.3.0'
|
VERSION = '4.3.1'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_development_dependency 'rake'
|
s.add_development_dependency 'rake'
|
||||||
s.add_development_dependency 'appraisal'
|
s.add_development_dependency 'appraisal'
|
||||||
s.add_development_dependency 'activesupport', '>= 3.0.0'
|
s.add_development_dependency 'activesupport', '>= 3.0.0'
|
||||||
|
s.add_development_dependency 'actionpack', '>= 3.0.0'
|
||||||
s.add_development_dependency 'redis-activesupport'
|
s.add_development_dependency 'redis-activesupport'
|
||||||
s.add_development_dependency 'dalli'
|
s.add_development_dependency 'dalli'
|
||||||
s.add_development_dependency 'connection_pool'
|
s.add_development_dependency 'connection_pool'
|
||||||
|
|
|
||||||
17
spec/rack_attack_path_normalizer_spec.rb
Normal file
17
spec/rack_attack_path_normalizer_spec.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
require_relative 'spec_helper'
|
||||||
|
|
||||||
|
describe Rack::Attack::PathNormalizer do
|
||||||
|
subject { Rack::Attack::PathNormalizer }
|
||||||
|
|
||||||
|
it 'should have a normalize_path method' do
|
||||||
|
subject.normalize_path('/foo').must_equal '/foo'
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'FallbackNormalizer' do
|
||||||
|
subject { Rack::Attack::FallbackPathNormalizer }
|
||||||
|
|
||||||
|
it '#normalize_path does not change the path' do
|
||||||
|
subject.normalize_path('').must_equal ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -3,6 +3,17 @@ require_relative 'spec_helper'
|
||||||
describe 'Rack::Attack' do
|
describe 'Rack::Attack' do
|
||||||
allow_ok_requests
|
allow_ok_requests
|
||||||
|
|
||||||
|
describe 'normalizing paths' do
|
||||||
|
before do
|
||||||
|
Rack::Attack.blacklist("banned_path") {|req| req.path == '/foo' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'blocks requests with trailing slash' do
|
||||||
|
get '/foo/'
|
||||||
|
last_response.status.must_equal 403
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'blacklist' do
|
describe 'blacklist' do
|
||||||
before do
|
before do
|
||||||
@bad_ip = '1.2.3.4'
|
@bad_ip = '1.2.3.4'
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,17 @@ require "minitest/autorun"
|
||||||
require "minitest/pride"
|
require "minitest/pride"
|
||||||
require "rack/test"
|
require "rack/test"
|
||||||
require 'active_support'
|
require 'active_support'
|
||||||
|
require 'action_dispatch'
|
||||||
|
|
||||||
|
# Load Journey for Rails 3.2
|
||||||
|
require 'journey' if ActionPack::VERSION::MAJOR == 3
|
||||||
|
|
||||||
require "rack/attack"
|
require "rack/attack"
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require 'debugger'
|
require 'pry'
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
#nothing to do here
|
#nothing to do here
|
||||||
end
|
end
|
||||||
|
|
||||||
class MiniTest::Spec
|
class MiniTest::Spec
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue