Add Strict Transport Security protection

This commit is contained in:
Maciej Moleda 2016-01-18 11:40:35 +00:00
parent 74439099c0
commit 3627a9f13b
4 changed files with 70 additions and 0 deletions

View File

@ -74,6 +74,12 @@ Prevented by:
* `Rack::Protection::IPSpoofing`
## Helps to protect against protocol downgrade attacks and cookie hijacking
Prevented by:
* `Rack::Protection::StrictTransport` (not included by `use Rack::Protection`)
# Installation
gem install rack-protection

View File

@ -16,6 +16,7 @@ module Rack
autoload :RemoteToken, 'rack/protection/remote_token'
autoload :SessionHijacking, 'rack/protection/session_hijacking'
autoload :XSSHeader, 'rack/protection/xss_header'
autoload :StrictTransport, 'rack/protection/strict_transport'
def self.new(app, options = {})
# does not include: RemoteReferrer, AuthenticityToken and FormToken
@ -25,6 +26,7 @@ module Rack
use ::Rack::Protection::RemoteReferrer, options if use_these.include? :remote_referrer
use ::Rack::Protection::AuthenticityToken,options if use_these.include? :authenticity_token
use ::Rack::Protection::FormToken, options if use_these.include? :form_token
use ::Rack::Protection::StrictTransport, options if use_these.include? :strict_transport
use ::Rack::Protection::FrameOptions, options unless except.include? :frame_options
use ::Rack::Protection::HttpOrigin, options unless except.include? :http_origin
use ::Rack::Protection::IPSpoofing, options unless except.include? :ip_spoofing

View File

@ -0,0 +1,37 @@
require 'rack/protection'
module Rack
module Protection
##
# Prevented attack:: Protects against against protocol downgrade attacks and cookie hijacking.
# Supported browsers:: all
# More infos:: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
#
# browser will prevent any communications from being sent over HTTP
# to the specified domain and will instead send all communications over HTTPS.
# It also prevents HTTPS click through prompts on browsers.
#
# Options:
#
# max_age:: How long future requests to the domain should go over HTTPS; specified in seconds
# include_subdomains:: If all present and future subdomains will be HTTPS
class StrictTransport < Base
default_options :max_age => 31_536_000, :include_subdomains => false
def strict_transport
@strict_transport ||= begin
strict_transport = 'max-age=' + options[:max_age].to_s
strict_transport += '; includeSubDomains' if options[:include_subdomains]
strict_transport.to_str
end
end
def call(env)
status, headers, body = @app.call(env)
headers['Strict-Transport-Security'] ||= strict_transport
[status, headers, body]
end
end
end
end

View File

@ -0,0 +1,25 @@
describe Rack::Protection::StrictTransport do
it_behaves_like "any rack application"
it 'should set the Strict-Transport-Security header' do
expect(get('/', {}, 'wants' => 'text/html').headers["Strict-Transport-Security"]).to eq("max-age=31536000")
end
it 'should allow changing the max-age option' do
mock_app do
use Rack::Protection::StrictTransport, :max_age => 16_070_400
run DummyApp
end
expect(get('/', {}, 'wants' => 'text/html').headers["Strict-Transport-Security"]).to eq("max-age=16070400")
end
it 'should allow switching on the include_subdomains option' do
mock_app do
use Rack::Protection::StrictTransport, :include_subdomains => true
run DummyApp
end
expect(get('/', {}, 'wants' => 'text/html').headers["Strict-Transport-Security"]).to eq("max-age=31536000; includeSubDomains")
end
end