only set protection headers for html, fixes #31

This commit is contained in:
Konstantin Haase 2012-12-10 16:42:48 +01:00
parent 8010a8fe9a
commit 13f0d4dac3
5 changed files with 28 additions and 10 deletions

View File

@ -96,6 +96,11 @@ module Rack
end
alias default_reaction deny
def html?(headers)
type = headers.detect { |k,v| k.downcase == 'content-type' }.last[/^\w+\/\w+/]
type == 'text/html' or type == 'application/xhtml'
end
end
end
end

View File

@ -25,7 +25,8 @@ module Rack
def call(env)
status, headers, body = @app.call(env)
[status, header.merge(headers), body]
headers = header.merge(headers) if options[:nosniff] and html?(headers)
[status, headers, body]
end
end
end

View File

@ -4,7 +4,11 @@ describe Rack::Protection::FrameOptions do
it_behaves_like "any rack application"
it 'should set the X-Frame-Options' do
get('/').headers["X-Frame-Options"].should == "sameorigin"
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "sameorigin"
end
it 'should not set the X-Frame-Options for other content types' do
get('/', {}, 'wants' => 'text/foo').headers["X-Frame-Options"].should be_nil
end
it 'should allow changing the protection mode' do
@ -14,11 +18,11 @@ describe Rack::Protection::FrameOptions do
run DummyApp
end
get('/').headers["X-Frame-Options"].should == "deny"
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "deny"
end
it 'should not override the header if already set' do
mock_app with_headers("X-Frame-Options" => "allow")
get('/').headers["X-Frame-Options"].should == "allow"
get('/', {}, 'wants' => 'text/html').headers["X-Frame-Options"].should == "allow"
end
end

View File

@ -25,7 +25,7 @@ module DummyApp
def self.call(env)
Thread.current[:last_env] = env
body = (env['REQUEST_METHOD'] == 'HEAD' ? '' : 'ok')
[200, {'Content-Type' => 'text/plain'}, [body]]
[200, {'Content-Type' => env['wants'] || 'text/plain'}, [body]]
end
end

View File

@ -4,7 +4,15 @@ describe Rack::Protection::XSSHeader do
it_behaves_like "any rack application"
it 'should set the X-XSS-Protection' do
get('/').headers["X-XSS-Protection"].should == "1; mode=block"
get('/', {}, 'wants' => 'text/html;charset=utf-8').headers["X-XSS-Protection"].should == "1; mode=block"
end
it 'should set the X-XSS-Protection for XHTML' do
get('/', {}, 'wants' => 'application/xhtml+xml').headers["X-XSS-Protection"].should == "1; mode=block"
end
it 'should not set the X-XSS-Protection for other content types' do
get('/', {}, 'wants' => 'application/foo').headers["X-XSS-Protection"].should be_nil
end
it 'should allow changing the protection mode' do
@ -14,16 +22,16 @@ describe Rack::Protection::XSSHeader do
run DummyApp
end
get('/').headers["X-XSS-Protection"].should == "1; mode=foo"
get('/', {}, 'wants' => 'application/xhtml').headers["X-XSS-Protection"].should == "1; mode=foo"
end
it 'should not override the header if already set' do
mock_app with_headers("X-XSS-Protection" => "0")
get('/').headers["X-XSS-Protection"].should == "0"
get('/', {}, 'wants' => 'text/html').headers["X-XSS-Protection"].should == "0"
end
it 'should set the X-Content-Type-Options' do
get('/').header["X-Content-Type-Options"].should == "nosniff"
get('/', {}, 'wants' => 'text/html').header["X-Content-Type-Options"].should == "nosniff"
end
it 'should allow changing the nosniff-mode off' do
@ -37,6 +45,6 @@ describe Rack::Protection::XSSHeader do
it 'should not override the header if already set X-Content-Type-Options' do
mock_app with_headers("X-Content-Type-Options" => "sniff")
get('/').headers["X-Content-Type-Options"].should == "sniff"
get('/', {}, 'wants' => 'text/html').headers["X-Content-Type-Options"].should == "sniff"
end
end