remove NoReferrer, instead, take an option for that

This commit is contained in:
Konstantin Haase 2011-06-20 13:08:39 +02:00
parent 6a8d4a0359
commit fcce195bc8
6 changed files with 32 additions and 54 deletions

View File

@ -41,10 +41,8 @@ Prevented by:
* `Rack::Protection::AuthenticityToken` (not included by `use Rack::Protection`)
* `Rack::Protection::FormToken` (not included by `use Rack::Protection`)
* `Rack::Protection::JsonCsrf`
* `Rack::Protection::NoReferrer` (not included by `use Rack::Protection`)
* `Rack::Protection::RemoteReferrer` (not included by `use Rack::Protection`)
* `Rack::Protection::RemoteToken`
## Cross Site Scripting
Prevented by:

View File

@ -10,7 +10,6 @@ module Rack
autoload :FrameOptions, 'rack/protection/frame_options'
autoload :IPSpoofing, 'rack/protection/ip_spoofing'
autoload :JsonCsrf, 'rack/protection/json_csrf'
autoload :NoReferrer, 'rack/protection/no_referrer'
autoload :PathTraversal, 'rack/protection/path_traversal'
autoload :RemoteReferrer, 'rack/protection/remote_referrer'
autoload :RemoteToken, 'rack/protection/remote_token'
@ -18,7 +17,7 @@ module Rack
autoload :XSSHeader, 'rack/protection/xss_header'
def self.new(app, options = {})
# does not include: AuthenticityToken, FormToken and NoReferrer
# does not include: RemoteReferrer, AuthenticityToken and FormToken
except = Array options[:except]
Rack::Builder.new do
use EscapedParams, options unless except.include? :escaped_params

View File

@ -9,7 +9,8 @@ module Rack
DEFAULT_OPTIONS = {
:reaction => :default_reaction, :logging => true,
:message => 'Forbidden', :encryptor => Digest::SHA1,
:session_key => 'rack.session', :status => 403
:session_key => 'rack.session', :status => 403,
:allow_empty_referrer => true
}
attr_reader :app, :options
@ -75,8 +76,9 @@ module Rack
end
def referrer(env)
ref = env['HTTP_REFERER']
URI.parse(ref).host || Request.new(env).host if ref and not ref.empty?
ref = env['HTTP_REFERER'].to_s
return if !options[:allow_empty_referrer] and ref.empty?
URI.parse(ref).host || Request.new(env).host
end
def random_string(secure = defined? SecureRandom)

View File

@ -1,23 +0,0 @@
require 'rack/protection'
module Rack
module Protection
##
# Prevented attack:: CSRF
# Supported browsers:: all
# More infos:: http://en.wikipedia.org/wiki/Cross-site_request_forgery
#
# Only accepts unsafe HTTP requests if the Referer [sic] header is set.
# Combine with RemoteRefferer for optimal security.
#
# This middleware is not used when using the Rack::Protection collection,
# since it renders web services unusable.
class NoReferrer < Base
default_reaction :deny
def accepts?(env)
safe?(env) or not env['HTTP_REFERER'].to_s.empty?
end
end
end
end

View File

@ -1,21 +0,0 @@
require File.expand_path('../spec_helper.rb', __FILE__)
describe Rack::Protection::NoReferrer do
it_behaves_like "any rack application"
it "should not allow post request without a referrer" do
post('/').should_not be_ok
end
it "should allow post request with a relative referrer" do
post('/', {}, 'HTTP_REFERER' => '/').should be_ok
end
it "should allow post request with an absolute referrer" do
post('/', {}, 'HTTP_REFERER' => 'http://google.com').should be_ok
end
it "should not allow post request with an empty referrer" do
post('/', {}, 'HTTP_REFERER' => '').should_not be_ok
end
end

View File

@ -2,7 +2,30 @@ require File.expand_path('../spec_helper.rb', __FILE__)
describe Rack::Protection::RemoteReferrer do
it_behaves_like "any rack application"
it "accepts post requests with no referrer"
it "accepts post requests with a local referrer"
it "denies post requests with a remote referrer"
it "accepts post requests with no referrer" do
post('/').should be_ok
end
it "does not accept post requests with no referrer if allow_empty_referrer is false" do
mock_app do
use Rack::Protection::RemoteReferrer, :allow_empty_referrer => false
run DummyApp
end
post('/').should_not be_ok
end
it "should allow post request with a relative referrer" do
post('/', {}, 'HTTP_REFERER' => '/').should be_ok
end
it "accepts post requests with the same host in the referrer" do
post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.com')
last_response.should be_ok
end
it "denies post requests with a remote referrer" do
post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org')
last_response.should_not be_ok
end
end