rack-protection 1.2.0 → 1.3.1
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.
- data/README.md +2 -22
- data/lib/rack/protection.rb +2 -0
- data/lib/rack/protection/base.rb +11 -1
- data/lib/rack/protection/escaped_params.rb +1 -1
- data/lib/rack/protection/frame_options.rb +6 -1
- data/lib/rack/protection/http_origin.rb +32 -0
- data/lib/rack/protection/json_csrf.rb +1 -1
- data/lib/rack/protection/path_traversal.rb +1 -1
- data/lib/rack/protection/session_hijacking.rb +2 -1
- data/lib/rack/protection/version.rb +1 -1
- data/lib/rack/protection/xss_header.rb +9 -3
- data/rack-protection.gemspec +25 -5
- data/spec/escaped_params_spec.rb +10 -0
- data/spec/frame_options_spec.rb +19 -4
- data/spec/http_origin_spec.rb +38 -0
- data/spec/json_csrf_spec.rb +8 -0
- data/spec/protection_spec.rb +17 -0
- data/spec/session_hijacking_spec.rb +14 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/xss_header_spec.rb +29 -3
- metadata +47 -11
data/README.md
CHANGED
@@ -43,12 +43,13 @@ Prevented by:
|
|
43
43
|
* `Rack::Protection::JsonCsrf`
|
44
44
|
* `Rack::Protection::RemoteReferrer` (not included by `use Rack::Protection`)
|
45
45
|
* `Rack::Protection::RemoteToken`
|
46
|
+
* `Rack::Protection::HttpOrigin`
|
46
47
|
|
47
48
|
## Cross Site Scripting
|
48
49
|
|
49
50
|
Prevented by:
|
50
51
|
|
51
|
-
* `Rack::Protection::EscapedParams`
|
52
|
+
* `Rack::Protection::EscapedParams` (not included by `use Rack::Protection`)
|
52
53
|
* `Rack::Protection::XssHeader` (Internet Explorer only)
|
53
54
|
|
54
55
|
## Clickjacking
|
@@ -79,24 +80,3 @@ Prevented by:
|
|
79
80
|
|
80
81
|
gem install rack-protection
|
81
82
|
|
82
|
-
# History
|
83
|
-
|
84
|
-
## v0.1.0 (2011/06/20)
|
85
|
-
|
86
|
-
First public release.
|
87
|
-
|
88
|
-
## v1.0.0 (2011/09/02)
|
89
|
-
|
90
|
-
First stable release.
|
91
|
-
|
92
|
-
Changes:
|
93
|
-
|
94
|
-
* Fix bug in JsonCsrf
|
95
|
-
|
96
|
-
## v1.1.0 (2011/09/03)
|
97
|
-
|
98
|
-
Second public release.
|
99
|
-
|
100
|
-
Changes:
|
101
|
-
|
102
|
-
* Dependency on `escape_utils` is now optional
|
data/lib/rack/protection.rb
CHANGED
@@ -8,6 +8,7 @@ module Rack
|
|
8
8
|
autoload :EscapedParams, 'rack/protection/escaped_params'
|
9
9
|
autoload :FormToken, 'rack/protection/form_token'
|
10
10
|
autoload :FrameOptions, 'rack/protection/frame_options'
|
11
|
+
autoload :HttpOrigin, 'rack/protection/http_origin'
|
11
12
|
autoload :IPSpoofing, 'rack/protection/ip_spoofing'
|
12
13
|
autoload :JsonCsrf, 'rack/protection/json_csrf'
|
13
14
|
autoload :PathTraversal, 'rack/protection/path_traversal'
|
@@ -21,6 +22,7 @@ module Rack
|
|
21
22
|
except = Array options[:except]
|
22
23
|
Rack::Builder.new do
|
23
24
|
use ::Rack::Protection::FrameOptions, options unless except.include? :frame_options
|
25
|
+
use ::Rack::Protection::HttpOrigin, options unless except.include? :http_origin
|
24
26
|
use ::Rack::Protection::IPSpoofing, options unless except.include? :ip_spoofing
|
25
27
|
use ::Rack::Protection::JsonCsrf, options unless except.include? :json_csrf
|
26
28
|
use ::Rack::Protection::PathTraversal, options unless except.include? :path_traversal
|
data/lib/rack/protection/base.rb
CHANGED
@@ -10,7 +10,8 @@ module Rack
|
|
10
10
|
:reaction => :default_reaction, :logging => true,
|
11
11
|
:message => 'Forbidden', :encryptor => Digest::SHA1,
|
12
12
|
:session_key => 'rack.session', :status => 403,
|
13
|
-
:allow_empty_referrer => true
|
13
|
+
:allow_empty_referrer => true,
|
14
|
+
:html_types => %w[text/html application/xhtml]
|
14
15
|
}
|
15
16
|
|
16
17
|
attr_reader :app, :options
|
@@ -81,6 +82,10 @@ module Rack
|
|
81
82
|
URI.parse(ref).host || Request.new(env).host
|
82
83
|
end
|
83
84
|
|
85
|
+
def origin(env)
|
86
|
+
env['HTTP_ORIGIN'] || env['HTTP_X_ORIGIN']
|
87
|
+
end
|
88
|
+
|
84
89
|
def random_string(secure = defined? SecureRandom)
|
85
90
|
secure ? SecureRandom.hex(32) : "%032x" % rand(2**128-1)
|
86
91
|
rescue NotImplementedError
|
@@ -92,6 +97,11 @@ module Rack
|
|
92
97
|
end
|
93
98
|
|
94
99
|
alias default_reaction deny
|
100
|
+
|
101
|
+
def html?(headers)
|
102
|
+
return false unless header = headers.detect { |k,v| k.downcase == 'content-type' }
|
103
|
+
options[:html_types].include? header.last[/^\w+\/\w+/]
|
104
|
+
end
|
95
105
|
end
|
96
106
|
end
|
97
107
|
end
|
@@ -18,8 +18,13 @@ module Rack
|
|
18
18
|
# to allow embedding from the same origin (default).
|
19
19
|
class FrameOptions < XSSHeader
|
20
20
|
default_options :frame_options => :sameorigin
|
21
|
+
|
21
22
|
def header
|
22
|
-
|
23
|
+
@header ||= begin
|
24
|
+
frame_options = options[:frame_options]
|
25
|
+
frame_options = options[:frame_options].to_s.upcase unless frame_options.respond_to? :to_str
|
26
|
+
{ 'X-Frame-Options' => frame_options.to_str }
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rack/protection'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Protection
|
5
|
+
##
|
6
|
+
# Prevented attack:: CSRF
|
7
|
+
# Supported browsers:: Google Chrome 2, Safari 4 and later
|
8
|
+
# More infos:: http://en.wikipedia.org/wiki/Cross-site_request_forgery
|
9
|
+
# http://tools.ietf.org/html/draft-abarth-origin
|
10
|
+
#
|
11
|
+
# Does not accept unsafe HTTP requests when value of Origin HTTP request header
|
12
|
+
# does not match default or whitelisted URIs.
|
13
|
+
class HttpOrigin < Base
|
14
|
+
default_reaction :deny
|
15
|
+
|
16
|
+
def accepts?(env)
|
17
|
+
# only for unsafe request methods
|
18
|
+
safe?(env) and return true
|
19
|
+
# ignore if origin is not set
|
20
|
+
origin = env['HTTP_ORIGIN'] or return true
|
21
|
+
|
22
|
+
# check base url
|
23
|
+
Request.new(env).base_url == origin and return true
|
24
|
+
|
25
|
+
# check whitelist
|
26
|
+
options[:origin_whitelist] or return false
|
27
|
+
options[:origin_whitelist].include?(origin)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -16,7 +16,7 @@ module Rack
|
|
16
16
|
def call(env)
|
17
17
|
status, headers, body = app.call(env)
|
18
18
|
if headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
|
19
|
-
if referrer(env) != Request.new(env).host
|
19
|
+
if origin(env).nil? and referrer(env) != Request.new(env).host
|
20
20
|
result = react(env)
|
21
21
|
warn env, "attack prevented by #{self.class}"
|
22
22
|
end
|
@@ -12,7 +12,7 @@ module Rack
|
|
12
12
|
class PathTraversal < Base
|
13
13
|
def call(env)
|
14
14
|
path_was = env["PATH_INFO"]
|
15
|
-
env["PATH_INFO"] = cleanup path_was if path_was
|
15
|
+
env["PATH_INFO"] = cleanup path_was if path_was && !path_was.empty?
|
16
16
|
app.call env
|
17
17
|
ensure
|
18
18
|
env["PATH_INFO"] = path_was
|
@@ -12,15 +12,21 @@ module Rack
|
|
12
12
|
# Options:
|
13
13
|
# xss_mode:: How the browser should prevent the attack (default: :block)
|
14
14
|
class XSSHeader < Base
|
15
|
-
default_options :xss_mode => :block
|
15
|
+
default_options :xss_mode => :block, :nosniff => true
|
16
16
|
|
17
17
|
def header
|
18
|
-
|
18
|
+
headers = {
|
19
|
+
'X-XSS-Protection' => "1; mode=#{options[:xss_mode]}",
|
20
|
+
'X-Content-Type-Options' => "nosniff"
|
21
|
+
}
|
22
|
+
headers.delete("X-Content-Type-Options") unless options[:nosniff]
|
23
|
+
headers
|
19
24
|
end
|
20
25
|
|
21
26
|
def call(env)
|
22
27
|
status, headers, body = @app.call(env)
|
23
|
-
|
28
|
+
headers = header.merge(headers) if options[:nosniff] and html?(headers)
|
29
|
+
[status, headers, body]
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
data/rack-protection.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
# general infos
|
4
4
|
s.name = "rack-protection"
|
5
|
-
s.version = "1.
|
5
|
+
s.version = "1.3.1"
|
6
6
|
s.description = "You should use protection!"
|
7
7
|
s.homepage = "http://github.com/rkh/rack-protection"
|
8
8
|
s.summary = s.description
|
@@ -10,21 +10,39 @@ Gem::Specification.new do |s|
|
|
10
10
|
# generated from git shortlog -sn
|
11
11
|
s.authors = [
|
12
12
|
"Konstantin Haase",
|
13
|
-
"
|
13
|
+
"Alex Rodionov",
|
14
|
+
"Chris Heald",
|
15
|
+
"Chris Mytton",
|
14
16
|
"Corey Ward",
|
15
17
|
"David Kellum",
|
16
18
|
"Fojas",
|
17
|
-
"
|
19
|
+
"Mael Clerambault",
|
20
|
+
"Martin Mauch",
|
21
|
+
"SAKAI, Kazuaki",
|
22
|
+
"Stanislav Savulchik",
|
23
|
+
"Steve Agalloco",
|
24
|
+
"Akzhan Abdulin",
|
25
|
+
"TOBY",
|
26
|
+
"Bjørge Næss"
|
18
27
|
]
|
19
28
|
|
20
29
|
# generated from git shortlog -sne
|
21
30
|
s.email = [
|
22
31
|
"konstantin.mailinglists@googlemail.com",
|
23
|
-
"
|
32
|
+
"p0deje@gmail.com",
|
33
|
+
"cheald@gmail.com",
|
34
|
+
"self@hecticjeff.net",
|
24
35
|
"coreyward@me.com",
|
25
36
|
"dek-oss@gravitext.com",
|
26
37
|
"developer@fojasaur.us",
|
27
|
-
"
|
38
|
+
"mael@clerambault.fr",
|
39
|
+
"martin.mauch@gmail.com",
|
40
|
+
"kaz.july.7@gmail.com",
|
41
|
+
"s.savulchik@gmail.com",
|
42
|
+
"steve.agalloco@gmail.com",
|
43
|
+
"akzhan.abdulin@gmail.com",
|
44
|
+
"toby.net.info.mail+git@gmail.com",
|
45
|
+
"bjoerge@bengler.no"
|
28
46
|
]
|
29
47
|
|
30
48
|
# generated from git ls-files
|
@@ -39,6 +57,7 @@ Gem::Specification.new do |s|
|
|
39
57
|
"lib/rack/protection/escaped_params.rb",
|
40
58
|
"lib/rack/protection/form_token.rb",
|
41
59
|
"lib/rack/protection/frame_options.rb",
|
60
|
+
"lib/rack/protection/http_origin.rb",
|
42
61
|
"lib/rack/protection/ip_spoofing.rb",
|
43
62
|
"lib/rack/protection/json_csrf.rb",
|
44
63
|
"lib/rack/protection/path_traversal.rb",
|
@@ -52,6 +71,7 @@ Gem::Specification.new do |s|
|
|
52
71
|
"spec/escaped_params_spec.rb",
|
53
72
|
"spec/form_token_spec.rb",
|
54
73
|
"spec/frame_options_spec.rb",
|
74
|
+
"spec/http_origin_spec.rb",
|
55
75
|
"spec/ip_spoofing_spec.rb",
|
56
76
|
"spec/json_csrf_spec.rb",
|
57
77
|
"spec/path_traversal_spec.rb",
|
data/spec/escaped_params_spec.rb
CHANGED
@@ -30,5 +30,15 @@ describe Rack::Protection::EscapedParams do
|
|
30
30
|
get '/', :foo => {:bar => "<bar>"}
|
31
31
|
body.should == '<bar>'
|
32
32
|
end
|
33
|
+
|
34
|
+
it 'leaves cache-breaker params untouched' do
|
35
|
+
mock_app do |env|
|
36
|
+
request = Rack::Request.new(env)
|
37
|
+
[200, {'Content-Type' => 'text/plain'}, ['hi']]
|
38
|
+
end
|
39
|
+
|
40
|
+
get '/?95df8d9bf5237ad08df3115ee74dcb10'
|
41
|
+
body.should == 'hi'
|
42
|
+
end
|
33
43
|
end
|
34
44
|
end
|
data/spec/frame_options_spec.rb
CHANGED
@@ -3,8 +3,12 @@ require File.expand_path('../spec_helper.rb', __FILE__)
|
|
3
3
|
describe Rack::Protection::FrameOptions do
|
4
4
|
it_behaves_like "any rack application"
|
5
5
|
|
6
|
-
it 'should set the X-
|
7
|
-
get('/').headers["X-Frame-Options"].should == "
|
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
|
8
12
|
end
|
9
13
|
|
10
14
|
it 'should allow changing the protection mode' do
|
@@ -14,11 +18,22 @@ describe Rack::Protection::FrameOptions do
|
|
14
18
|
run DummyApp
|
15
19
|
end
|
16
20
|
|
17
|
-
get('/').headers["X-Frame-Options"].should == "
|
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"
|
18
33
|
end
|
19
34
|
|
20
35
|
it 'should not override the header if already set' do
|
21
36
|
mock_app with_headers("X-Frame-Options" => "allow")
|
22
|
-
get('/').headers["X-Frame-Options"].should == "allow"
|
37
|
+
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "allow"
|
23
38
|
end
|
24
39
|
end
|
@@ -0,0 +1,38 @@
|
|
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
|
data/spec/json_csrf_spec.rb
CHANGED
@@ -12,6 +12,14 @@ describe Rack::Protection::JsonCsrf do
|
|
12
12
|
get('/', {}, 'HTTP_REFERER' => 'http://evil.com').should_not be_ok
|
13
13
|
end
|
14
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
|
+
|
15
23
|
it "accepts get requests with json responses with a local referrer" do
|
16
24
|
get('/', {}, 'HTTP_REFERER' => '/').should be_ok
|
17
25
|
end
|
data/spec/protection_spec.rb
CHANGED
@@ -17,4 +17,21 @@ describe Rack::Protection do
|
|
17
17
|
get '/', {}, 'rack.session' => session, 'HTTP_FOO' => 'BAR'
|
18
18
|
session.should be_empty
|
19
19
|
end
|
20
|
+
|
21
|
+
describe "#html?" do
|
22
|
+
context "given an appropriate content-type header" do
|
23
|
+
subject { Rack::Protection::Base.new(nil).html? 'content-type' => "text/html" }
|
24
|
+
it { should be_true }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "given an inappropriate content-type header" do
|
28
|
+
subject { Rack::Protection::Base.new(nil).html? 'content-type' => "image/gif" }
|
29
|
+
it { should be_false }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "given no content-type header" do
|
33
|
+
subject { Rack::Protection::Base.new(nil).html?({}) }
|
34
|
+
it { should be_false }
|
35
|
+
end
|
36
|
+
end
|
20
37
|
end
|
@@ -31,6 +31,20 @@ describe Rack::Protection::SessionHijacking do
|
|
31
31
|
session.should be_empty
|
32
32
|
end
|
33
33
|
|
34
|
+
it "accepts requests with the same Accept-Language header" do
|
35
|
+
session = {:foo => :bar}
|
36
|
+
get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
|
37
|
+
get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
|
38
|
+
session.should_not be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it "comparison of Accept-Language header is not case sensitive" do
|
42
|
+
session = {:foo => :bar}
|
43
|
+
get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'a'
|
44
|
+
get '/', {}, 'rack.session' => session, 'HTTP_ACCEPT_LANGUAGE' => 'A'
|
45
|
+
session.should_not be_empty
|
46
|
+
end
|
47
|
+
|
34
48
|
it "accepts requests with a changing Version header"do
|
35
49
|
session = {:foo => :bar}
|
36
50
|
get '/', {}, 'rack.session' => session, 'HTTP_VERSION' => '1.0'
|
data/spec/spec_helper.rb
CHANGED
@@ -24,7 +24,8 @@ end
|
|
24
24
|
module DummyApp
|
25
25
|
def self.call(env)
|
26
26
|
Thread.current[:last_env] = env
|
27
|
-
[
|
27
|
+
body = (env['REQUEST_METHOD'] == 'HEAD' ? '' : 'ok')
|
28
|
+
[200, {'Content-Type' => env['wants'] || 'text/plain'}, [body]]
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
data/spec/xss_header_spec.rb
CHANGED
@@ -4,7 +4,15 @@ describe Rack::Protection::XSSHeader do
|
|
4
4
|
it_behaves_like "any rack application"
|
5
5
|
|
6
6
|
it 'should set the X-XSS-Protection' do
|
7
|
-
get('/').headers["X-XSS-Protection"].should == "1; mode=block"
|
7
|
+
get('/', {}, 'wants' => 'text/html;charset=utf-8').headers["X-XSS-Protection"].should == "1; mode=block"
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should set the X-XSS-Protection for XHTML' do
|
11
|
+
get('/', {}, 'wants' => 'application/xhtml+xml').headers["X-XSS-Protection"].should == "1; mode=block"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should not set the X-XSS-Protection for other content types' do
|
15
|
+
get('/', {}, 'wants' => 'application/foo').headers["X-XSS-Protection"].should be_nil
|
8
16
|
end
|
9
17
|
|
10
18
|
it 'should allow changing the protection mode' do
|
@@ -14,11 +22,29 @@ describe Rack::Protection::XSSHeader do
|
|
14
22
|
run DummyApp
|
15
23
|
end
|
16
24
|
|
17
|
-
get('/').headers["X-XSS-Protection"].should == "1; mode=foo"
|
25
|
+
get('/', {}, 'wants' => 'application/xhtml').headers["X-XSS-Protection"].should == "1; mode=foo"
|
18
26
|
end
|
19
27
|
|
20
28
|
it 'should not override the header if already set' do
|
21
29
|
mock_app with_headers("X-XSS-Protection" => "0")
|
22
|
-
get('/').headers["X-XSS-Protection"].should == "0"
|
30
|
+
get('/', {}, 'wants' => 'text/html').headers["X-XSS-Protection"].should == "0"
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should set the X-Content-Type-Options' do
|
34
|
+
get('/', {}, 'wants' => 'text/html').header["X-Content-Type-Options"].should == "nosniff"
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should allow changing the nosniff-mode off' do
|
38
|
+
mock_app do
|
39
|
+
use Rack::Protection::XSSHeader, :nosniff => false
|
40
|
+
run DummyApp
|
41
|
+
end
|
42
|
+
|
43
|
+
get('/').headers["X-Content-Type-Options"].should be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should not override the header if already set X-Content-Type-Options' do
|
47
|
+
mock_app with_headers("X-Content-Type-Options" => "sniff")
|
48
|
+
get('/', {}, 'wants' => 'text/html').headers["X-Content-Type-Options"].should == "sniff"
|
23
49
|
end
|
24
50
|
end
|
metadata
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-protection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Konstantin Haase
|
9
|
-
-
|
9
|
+
- Alex Rodionov
|
10
|
+
- Chris Heald
|
11
|
+
- Chris Mytton
|
10
12
|
- Corey Ward
|
11
13
|
- David Kellum
|
12
14
|
- Fojas
|
15
|
+
- Mael Clerambault
|
13
16
|
- Martin Mauch
|
17
|
+
- SAKAI, Kazuaki
|
18
|
+
- Stanislav Savulchik
|
19
|
+
- Steve Agalloco
|
20
|
+
- Akzhan Abdulin
|
21
|
+
- TOBY
|
22
|
+
- Bjørge Næss
|
14
23
|
autorequire:
|
15
24
|
bindir: bin
|
16
25
|
cert_chain: []
|
17
|
-
date:
|
26
|
+
date: 2012-12-10 00:00:00.000000000 Z
|
18
27
|
dependencies:
|
19
28
|
- !ruby/object:Gem::Dependency
|
20
29
|
name: rack
|
21
|
-
requirement:
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
22
31
|
none: false
|
23
32
|
requirements:
|
24
33
|
- - ! '>='
|
@@ -26,10 +35,15 @@ dependencies:
|
|
26
35
|
version: '0'
|
27
36
|
type: :runtime
|
28
37
|
prerelease: false
|
29
|
-
version_requirements:
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
30
44
|
- !ruby/object:Gem::Dependency
|
31
45
|
name: rack-test
|
32
|
-
requirement:
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
33
47
|
none: false
|
34
48
|
requirements:
|
35
49
|
- - ! '>='
|
@@ -37,10 +51,15 @@ dependencies:
|
|
37
51
|
version: '0'
|
38
52
|
type: :development
|
39
53
|
prerelease: false
|
40
|
-
version_requirements:
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
41
60
|
- !ruby/object:Gem::Dependency
|
42
61
|
name: rspec
|
43
|
-
requirement:
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
44
63
|
none: false
|
45
64
|
requirements:
|
46
65
|
- - ~>
|
@@ -48,15 +67,29 @@ dependencies:
|
|
48
67
|
version: '2.0'
|
49
68
|
type: :development
|
50
69
|
prerelease: false
|
51
|
-
version_requirements:
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
52
76
|
description: You should use protection!
|
53
77
|
email:
|
54
78
|
- konstantin.mailinglists@googlemail.com
|
55
|
-
-
|
79
|
+
- p0deje@gmail.com
|
80
|
+
- cheald@gmail.com
|
81
|
+
- self@hecticjeff.net
|
56
82
|
- coreyward@me.com
|
57
83
|
- dek-oss@gravitext.com
|
58
84
|
- developer@fojasaur.us
|
85
|
+
- mael@clerambault.fr
|
59
86
|
- martin.mauch@gmail.com
|
87
|
+
- kaz.july.7@gmail.com
|
88
|
+
- s.savulchik@gmail.com
|
89
|
+
- steve.agalloco@gmail.com
|
90
|
+
- akzhan.abdulin@gmail.com
|
91
|
+
- toby.net.info.mail+git@gmail.com
|
92
|
+
- bjoerge@bengler.no
|
60
93
|
executables: []
|
61
94
|
extensions: []
|
62
95
|
extra_rdoc_files: []
|
@@ -71,6 +104,7 @@ files:
|
|
71
104
|
- lib/rack/protection/escaped_params.rb
|
72
105
|
- lib/rack/protection/form_token.rb
|
73
106
|
- lib/rack/protection/frame_options.rb
|
107
|
+
- lib/rack/protection/http_origin.rb
|
74
108
|
- lib/rack/protection/ip_spoofing.rb
|
75
109
|
- lib/rack/protection/json_csrf.rb
|
76
110
|
- lib/rack/protection/path_traversal.rb
|
@@ -84,6 +118,7 @@ files:
|
|
84
118
|
- spec/escaped_params_spec.rb
|
85
119
|
- spec/form_token_spec.rb
|
86
120
|
- spec/frame_options_spec.rb
|
121
|
+
- spec/http_origin_spec.rb
|
87
122
|
- spec/ip_spoofing_spec.rb
|
88
123
|
- spec/json_csrf_spec.rb
|
89
124
|
- spec/path_traversal_spec.rb
|
@@ -113,8 +148,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
148
|
version: '0'
|
114
149
|
requirements: []
|
115
150
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.8.
|
151
|
+
rubygems_version: 1.8.23
|
117
152
|
signing_key:
|
118
153
|
specification_version: 3
|
119
154
|
summary: You should use protection!
|
120
155
|
test_files: []
|
156
|
+
has_rdoc:
|