diff --git a/rack-protection/lib/rack/protection.rb b/rack-protection/lib/rack/protection.rb index 23424a0ae8..b758621966 100644 --- a/rack-protection/lib/rack/protection.rb +++ b/rack-protection/lib/rack/protection.rb @@ -23,6 +23,11 @@ def self.new(app, options = {}) # does not include: RemoteReferrer, AuthenticityToken and FormToken except = Array options[:except] use_these = Array options[:use] + + if options.fetch(:without_session, false) + except += [:session_hijacking, :remote_token] + end + Rack::Builder.new do use ::Rack::Protection::RemoteReferrer, options if use_these.include? :remote_referrer use ::Rack::Protection::AuthenticityToken, options if use_these.include? :authenticity_token diff --git a/rack-protection/spec/lib/rack/protection/protection_spec.rb b/rack-protection/spec/lib/rack/protection/protection_spec.rb index 35bd0ca1cf..a9afda2232 100644 --- a/rack-protection/spec/lib/rack/protection/protection_spec.rb +++ b/rack-protection/spec/lib/rack/protection/protection_spec.rb @@ -100,4 +100,28 @@ it { expect(instrumenter).not_to receive(:instrument) } end end + + describe "new" do + it 'should allow disable session protection' do + mock_app do + use Rack::Protection, :without_session => true + run DummyApp + end + + session = {:foo => :bar} + get '/', {}, 'rack.session' => session, 'HTTP_USER_AGENT' => 'a' + get '/', {}, 'rack.session' => session, 'HTTP_USER_AGENT' => 'b' + expect(session[:foo]).to eq :bar + end + + it 'should allow disable CSRF protection' do + mock_app do + use Rack::Protection, :without_session => true + run DummyApp + end + + post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org') + expect(last_response).to be_ok + end + end end