rack-protection 1.5.5 → 2.0.0.beta1

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-protection might be problematic. Click here for more details.

@@ -1,39 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::FrameOptions do
4
- it_behaves_like "any rack application"
5
-
6
- it 'should set the X-Frame-Options' do
7
- get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "SAMEORIGIN"
8
- end
9
-
10
- it 'should not set the X-Frame-Options for other content types' do
11
- get('/', {}, 'wants' => 'text/foo').headers["X-Frame-Options"].should be_nil
12
- end
13
-
14
- it 'should allow changing the protection mode' do
15
- # I have no clue what other modes are available
16
- mock_app do
17
- use Rack::Protection::FrameOptions, :frame_options => :deny
18
- run DummyApp
19
- end
20
-
21
- get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "DENY"
22
- end
23
-
24
-
25
- it 'should allow changing the protection mode to a string' do
26
- # I have no clue what other modes are available
27
- mock_app do
28
- use Rack::Protection::FrameOptions, :frame_options => "ALLOW-FROM foo"
29
- run DummyApp
30
- end
31
-
32
- get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "ALLOW-FROM foo"
33
- end
34
-
35
- it 'should not override the header if already set' do
36
- mock_app with_headers("X-Frame-Options" => "allow")
37
- get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "allow"
38
- end
39
- end
@@ -1,38 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::HttpOrigin do
4
- it_behaves_like "any rack application"
5
-
6
- before(:each) do
7
- mock_app do
8
- use Rack::Protection::HttpOrigin
9
- run DummyApp
10
- end
11
- end
12
-
13
- %w(GET HEAD POST PUT DELETE).each do |method|
14
- it "accepts #{method} requests with no Origin" do
15
- send(method.downcase, '/').should be_ok
16
- end
17
- end
18
-
19
- %w(GET HEAD).each do |method|
20
- it "accepts #{method} requests with non-whitelisted Origin" do
21
- send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://malicious.com').should be_ok
22
- end
23
- end
24
-
25
- %w(POST PUT DELETE).each do |method|
26
- it "denies #{method} requests with non-whitelisted Origin" do
27
- send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://malicious.com').should_not be_ok
28
- end
29
-
30
- it "accepts #{method} requests with whitelisted Origin" do
31
- mock_app do
32
- use Rack::Protection::HttpOrigin, :origin_whitelist => ['http://www.friend.com']
33
- run DummyApp
34
- end
35
- send(method.downcase, '/', {}, 'HTTP_ORIGIN' => 'http://www.friend.com').should be_ok
36
- end
37
- end
38
- end
@@ -1,35 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::IPSpoofing do
4
- it_behaves_like "any rack application"
5
-
6
- it 'accepts requests without X-Forward-For header' do
7
- get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4', 'HTTP_X_REAL_IP' => '4.3.2.1')
8
- last_response.should be_ok
9
- end
10
-
11
- it 'accepts requests with proper X-Forward-For header' do
12
- get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4',
13
- 'HTTP_X_FORWARDED_FOR' => '192.168.1.20, 1.2.3.4, 127.0.0.1')
14
- last_response.should be_ok
15
- end
16
-
17
- it 'denies requests where the client spoofs X-Forward-For but not the IP' do
18
- get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.4', 'HTTP_X_FORWARDED_FOR' => '1.2.3.5')
19
- last_response.should_not be_ok
20
- end
21
-
22
- it 'denies requests where the client spoofs the IP but not X-Forward-For' do
23
- get('/', {}, 'HTTP_CLIENT_IP' => '1.2.3.5',
24
- 'HTTP_X_FORWARDED_FOR' => '192.168.1.20, 1.2.3.4, 127.0.0.1')
25
- last_response.should_not be_ok
26
- end
27
-
28
- it 'denies requests where IP and X-Forward-For are spoofed but not X-Real-IP' do
29
- get('/', {},
30
- 'HTTP_CLIENT_IP' => '1.2.3.5',
31
- 'HTTP_X_FORWARDED_FOR' => '1.2.3.5',
32
- 'HTTP_X_REAL_IP' => '1.2.3.4')
33
- last_response.should_not be_ok
34
- end
35
- end
@@ -1,58 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::JsonCsrf do
4
- it_behaves_like "any rack application"
5
-
6
- describe 'json response' do
7
- before do
8
- mock_app { |e| [200, {'Content-Type' => 'application/json'}, []]}
9
- end
10
-
11
- it "denies get requests with json responses with a remote referrer" do
12
- get('/', {}, 'HTTP_REFERER' => 'http://evil.com').should_not be_ok
13
- end
14
-
15
- it "accepts requests with json responses with a remote referrer when there's an origin header set" do
16
- get('/', {}, 'HTTP_REFERER' => 'http://good.com', 'HTTP_ORIGIN' => 'http://good.com').should be_ok
17
- end
18
-
19
- it "accepts requests with json responses with a remote referrer when there's an x-origin header set" do
20
- get('/', {}, 'HTTP_REFERER' => 'http://good.com', 'HTTP_X_ORIGIN' => 'http://good.com').should be_ok
21
- end
22
-
23
- it "accepts get requests with json responses with a local referrer" do
24
- get('/', {}, 'HTTP_REFERER' => '/').should be_ok
25
- end
26
-
27
- it "accepts get requests with json responses with no referrer" do
28
- get('/', {}).should be_ok
29
- end
30
-
31
- it "accepts XHR requests" do
32
- get('/', {}, 'HTTP_REFERER' => 'http://evil.com', 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest').should be_ok
33
- end
34
-
35
- end
36
-
37
- describe 'not json response' do
38
-
39
- it "accepts get requests with 304 headers" do
40
- mock_app { |e| [304, {}, []]}
41
- get('/', {}).status.should == 304
42
- end
43
-
44
- end
45
-
46
- describe 'with drop_session as default reaction' do
47
- it 'still denies' do
48
- mock_app do
49
- use Rack::Protection, :reaction => :drop_session
50
- run proc { |e| [200, {'Content-Type' => 'application/json'}, []]}
51
- end
52
-
53
- session = {:foo => :bar}
54
- get('/', {}, 'HTTP_REFERER' => 'http://evil.com', 'rack.session' => session)
55
- last_response.should_not be_ok
56
- end
57
- end
58
- end
@@ -1,41 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::PathTraversal do
4
- it_behaves_like "any rack application"
5
-
6
- context 'escaping' do
7
- before do
8
- mock_app { |e| [200, {'Content-Type' => 'text/plain'}, [e['PATH_INFO']]] }
9
- end
10
-
11
- %w[/foo/bar /foo/bar/ / /.f /a.x].each do |path|
12
- it("does not touch #{path.inspect}") { get(path).body.should == path }
13
- end
14
-
15
- { # yes, this is ugly, feel free to change that
16
- '/..' => '/', '/a/../b' => '/b', '/a/../b/' => '/b/', '/a/.' => '/a/',
17
- '/%2e.' => '/', '/a/%2E%2e/b' => '/b', '/a%2f%2E%2e%2Fb/' => '/b/',
18
- '//' => '/', '/%2fetc%2Fpasswd' => '/etc/passwd'
19
- }.each do |a, b|
20
- it("replaces #{a.inspect} with #{b.inspect}") { get(a).body.should == b }
21
- end
22
-
23
- it 'should be able to deal with PATH_INFO = nil (fcgi?)' do
24
- app = Rack::Protection::PathTraversal.new(proc { 42 })
25
- app.call({}).should be == 42
26
- end
27
- end
28
-
29
- if "".respond_to?(:encoding) # Ruby 1.9+ M17N
30
- context "PATH_INFO's encoding" do
31
- before do
32
- @app = Rack::Protection::PathTraversal.new(proc { |e| [200, {'Content-Type' => 'text/plain'}, [e['PATH_INFO'].encoding.to_s]] })
33
- end
34
-
35
- it 'should remain unchanged as ASCII-8BIT' do
36
- body = @app.call({ 'PATH_INFO' => '/'.encode('ASCII-8BIT') })[2][0]
37
- body.should == 'ASCII-8BIT'
38
- end
39
- end
40
- end
41
- end
@@ -1,105 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection do
4
- it_behaves_like "any rack application"
5
-
6
- it 'passes on options' do
7
- mock_app do
8
- use Rack::Protection, :track => ['HTTP_FOO']
9
- run proc { |e| [200, {'Content-Type' => 'text/plain'}, ['hi']] }
10
- end
11
-
12
- session = {:foo => :bar}
13
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_ENCODING' => 'a'
14
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_ENCODING' => 'b'
15
- session[:foo].should be == :bar
16
-
17
- get '/', {}, 'rack.session' => session, 'HTTP_FOO' => 'BAR'
18
- session.should be_empty
19
- end
20
-
21
- it 'passes errors through if :reaction => :report is used' do
22
- mock_app do
23
- use Rack::Protection, :reaction => :report
24
- run proc { |e| [200, {'Content-Type' => 'text/plain'}, [e["protection.failed"].to_s]] }
25
- end
26
-
27
- session = {:foo => :bar}
28
- post('/', {}, 'rack.session' => session, 'HTTP_ORIGIN' => 'http://malicious.com')
29
- last_response.should be_ok
30
- body.should == "true"
31
- end
32
-
33
- describe "#react" do
34
- it 'prevents attacks and warns about it' do
35
- io = StringIO.new
36
- mock_app do
37
- use Rack::Protection, :logger => Logger.new(io)
38
- run DummyApp
39
- end
40
- post('/', {}, 'rack.session' => {}, 'HTTP_ORIGIN' => 'http://malicious.com')
41
- io.string.should match /prevented.*Origin/
42
- end
43
-
44
- it 'reports attacks if reaction is to report' do
45
- io = StringIO.new
46
- mock_app do
47
- use Rack::Protection, :reaction => :report, :logger => Logger.new(io)
48
- run DummyApp
49
- end
50
- post('/', {}, 'rack.session' => {}, 'HTTP_ORIGIN' => 'http://malicious.com')
51
- io.string.should match /reported.*Origin/
52
- io.string.should_not match /prevented.*Origin/
53
- end
54
-
55
- it 'passes errors to reaction method if specified' do
56
- io = StringIO.new
57
- Rack::Protection::Base.send(:define_method, :special) { |*args| io << args.inspect }
58
- mock_app do
59
- use Rack::Protection, :reaction => :special, :logger => Logger.new(io)
60
- run DummyApp
61
- end
62
- post('/', {}, 'rack.session' => {}, 'HTTP_ORIGIN' => 'http://malicious.com')
63
- io.string.should match /HTTP_ORIGIN.*malicious.com/
64
- io.string.should_not match /reported|prevented/
65
- end
66
- end
67
-
68
- describe "#html?" do
69
- context "given an appropriate content-type header" do
70
- subject { Rack::Protection::Base.new(nil).html? 'content-type' => "text/html" }
71
- it { should be_true }
72
- end
73
-
74
- context "given an inappropriate content-type header" do
75
- subject { Rack::Protection::Base.new(nil).html? 'content-type' => "image/gif" }
76
- it { should be_false }
77
- end
78
-
79
- context "given no content-type header" do
80
- subject { Rack::Protection::Base.new(nil).html?({}) }
81
- it { should be_false }
82
- end
83
- end
84
-
85
- describe "#instrument" do
86
- let(:env) { { 'rack.protection.attack' => 'base' } }
87
- let(:instrumenter) { double('Instrumenter') }
88
-
89
- after do
90
- app.instrument(env)
91
- end
92
-
93
- context 'with an instrumenter specified' do
94
- let(:app) { Rack::Protection::Base.new(nil, :instrumenter => instrumenter) }
95
-
96
- it { instrumenter.should_receive(:instrument).with('rack.protection', env) }
97
- end
98
-
99
- context 'with no instrumenter specified' do
100
- let(:app) { Rack::Protection::Base.new(nil) }
101
-
102
- it { instrumenter.should_not_receive(:instrument) }
103
- end
104
- end
105
- end
@@ -1,31 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::RemoteReferrer do
4
- it_behaves_like "any rack application"
5
-
6
- it "accepts post requests with no referrer" do
7
- post('/').should be_ok
8
- end
9
-
10
- it "does not accept post requests with no referrer if allow_empty_referrer is false" do
11
- mock_app do
12
- use Rack::Protection::RemoteReferrer, :allow_empty_referrer => false
13
- run DummyApp
14
- end
15
- post('/').should_not be_ok
16
- end
17
-
18
- it "should allow post request with a relative referrer" do
19
- post('/', {}, 'HTTP_REFERER' => '/').should be_ok
20
- end
21
-
22
- it "accepts post requests with the same host in the referrer" do
23
- post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.com')
24
- last_response.should be_ok
25
- end
26
-
27
- it "denies post requests with a remote referrer" do
28
- post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org')
29
- last_response.should_not be_ok
30
- end
31
- end
@@ -1,42 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::RemoteToken do
4
- it_behaves_like "any rack application"
5
-
6
- it "accepts post requests with no referrer" do
7
- post('/').should be_ok
8
- end
9
-
10
- it "accepts post requests with a local referrer" do
11
- post('/', {}, 'HTTP_REFERER' => '/').should be_ok
12
- end
13
-
14
- it "denies post requests with a remote referrer and no token" do
15
- post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org')
16
- last_response.should_not be_ok
17
- end
18
-
19
- it "accepts post requests with a remote referrer and correct X-CSRF-Token header" do
20
- post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org',
21
- 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "a")
22
- last_response.should be_ok
23
- end
24
-
25
- it "denies post requests with a remote referrer and wrong X-CSRF-Token header" do
26
- post('/', {}, 'HTTP_REFERER' => 'http://example.com/foo', 'HTTP_HOST' => 'example.org',
27
- 'rack.session' => {:csrf => "a"}, 'HTTP_X_CSRF_TOKEN' => "b")
28
- last_response.should_not be_ok
29
- end
30
-
31
- it "accepts post form requests with a remote referrer and correct authenticity_token field" do
32
- post('/', {"authenticity_token" => "a"}, 'HTTP_REFERER' => 'http://example.com/foo',
33
- 'HTTP_HOST' => 'example.org', 'rack.session' => {:csrf => "a"})
34
- last_response.should be_ok
35
- end
36
-
37
- it "denies post form requests with a remote referrer and wrong authenticity_token field" do
38
- post('/', {"authenticity_token" => "a"}, 'HTTP_REFERER' => 'http://example.com/foo',
39
- 'HTTP_HOST' => 'example.org', 'rack.session' => {:csrf => "b"})
40
- last_response.should_not be_ok
41
- end
42
- end
@@ -1,55 +0,0 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- describe Rack::Protection::SessionHijacking do
4
- it_behaves_like "any rack application"
5
-
6
- it "accepts a session without changes to tracked parameters" do
7
- session = {:foo => :bar}
8
- get '/', {}, 'rack.session' => session
9
- get '/', {}, 'rack.session' => session
10
- session[:foo].should == :bar
11
- end
12
-
13
- it "denies requests with a changing User-Agent header" do
14
- session = {:foo => :bar}
15
- get '/', {}, 'rack.session' => session, 'HTTP_USER_AGENT' => 'a'
16
- get '/', {}, 'rack.session' => session, 'HTTP_USER_AGENT' => 'b'
17
- session.should be_empty
18
- end
19
-
20
- it "accepts requests with a changing Accept-Encoding header" do
21
- # this is tested because previously it led to clearing the session
22
- session = {:foo => :bar}
23
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_ENCODING' => 'a'
24
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_ENCODING' => 'b'
25
- session.should_not be_empty
26
- end
27
-
28
- it "denies requests with a changing Accept-Language header" do
29
- session = {:foo => :bar}
30
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
31
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'b'
32
- session.should be_empty
33
- end
34
-
35
- it "accepts requests with the same Accept-Language header" do
36
- session = {:foo => :bar}
37
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
38
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
39
- session.should_not be_empty
40
- end
41
-
42
- it "comparison of Accept-Language header is not case sensitive" do
43
- session = {:foo => :bar}
44
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
45
- get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'A'
46
- session.should_not be_empty
47
- end
48
-
49
- it "accepts requests with a changing Version header"do
50
- session = {:foo => :bar}
51
- get '/', {}, 'rack.session' => session, 'HTTP_VERSION' => '1.0'
52
- get '/', {}, 'rack.session' => session, 'HTTP_VERSION' => '1.1'
53
- session[:foo].should == :bar
54
- end
55
- end