The 3.x branch was recently merged. See the upgrading to 3.x doc for instructions on how to upgrade including the differences and benefits of using the 3.x branch.
The 2.x branch will be maintained. The documentation below only applies to the 3.x branch. See the 2.x README for the old way of doing things.
The gem will automatically apply several headers that are related to security. This includes:
- Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack. CSP 2 Specification
- HTTP Strict Transport Security (HSTS) - Ensures the browser never visits the http version of a website. Protects from SSLStrip/Firesheep attacks. HSTS Specification
- X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. X-Frame-Options Specification
- X-XSS-Protection - Cross site scripting heuristic filter for IE/Chrome
- X-Content-Type-Options - Prevent content type sniffing
- X-Download-Options - Prevent file downloads opening
- X-Permitted-Cross-Domain-Policies - Restrict Adobe Flash Player's access to data
- Referrer-Policy - Referrer Policy draft
- Public Key Pinning - Pin certificate fingerprints in the browser to prevent man-in-the-middle attacks due to compromised Certificate Authorities. Public Key Pinning Specification
- Clear-Site-Data - Clearing browser data for origin. Clear-Site-Data specification.
It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes (when configured to do so).
secure_headers
is a library with a global config, per request overrides, and rack middleware that enables you customize your application settings.
For Rails 3+ applications, secure_headers
has a railtie
that should automatically include the middleware. If for some reason the middleware is not being included follow the instructions for Rails 2.
For Rails 2 or non-rails applications, an explicit statement is required to use the middleware component.
use SecureHeaders::Middleware
If you do not supply a default
configuration, exceptions will be raised. If you would like to use a default configuration (which is fairly locked down), just call SecureHeaders::Configuration.default
without any arguments or block.
All nil
values will fallback to their default values. SecureHeaders::OPT_OUT
will disable the header entirely.
SecureHeaders::Configuration.default do |config|
config.cookies = {
secure: true, # mark all cookies as "Secure"
httponly: true, # mark all cookies as "HttpOnly"
samesite: {
lax: true # mark all cookies as SameSite=lax
}
}
# Add "; preload" and submit the site to hstspreload.org for best protection.
config.hsts = "max-age=#{20.years.to_i}; includeSubdomains"
config.x_frame_options = "DENY"
config.x_content_type_options = "nosniff"
config.x_xss_protection = "1; mode=block"
config.x_download_options = "noopen"
config.x_permitted_cross_domain_policies = "none"
config.referrer_policy = "origin-when-cross-origin"
config.clear_site_data = [
"cache",
"cookies",
"storage",
"executionContexts"
]
config.csp = {
# "meta" values. these will shaped the header, but the values are not included in the header.
report_only: true, # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
# directive values: these values will directly translate into source directives
default_src: %w(https: 'self'),
base_uri: %w('self'),
block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
connect_src: %w(wss:),
font_src: %w('self' data:),
form_action: %w('self' github.com),
frame_ancestors: %w('none'),
img_src: %w(mycdn.com data:),
media_src: %w(utoob.com),
object_src: %w('self'),
plugin_types: %w(application/x-shockwave-flash),
script_src: %w('self'),
style_src: %w('unsafe-inline'),
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
report_uri: %w(https://report-uri.io/example-csp)
}
# This is available only from 3.5.0; use the `report_only: true` setting for 3.4.1 and below.
config.csp_report_only = config.csp.merge({
img_src: %w(somewhereelse.com),
report_uri: %w(https://report-uri.io/example-csp-report-only)
})
config.hpkp = {
report_only: false,
max_age: 60.days.to_i,
include_subdomains: true,
report_uri: "https://report-uri.io/example-hpkp",
pins: [
{sha256: "abc"},
{sha256: "123"}
]
}
end
All headers except for PublicKeyPins and ClearSiteData have a default value. The default set of headers is:
Content-Security-Policy: default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
Strict-Transport-Security: max-age=631138519
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-Xss-Protection: 1; mode=block
By default, the above CSP will be applied to all requests. If you only want to set a Report-Only header, opt-out of the default enforced header for clarity. The configuration will assume that if you only supply csp_report_only
that you intended to opt-out of csp
but that's for the sake of backwards compatibility and it will be removed in the future.
Configuration.default do |config|
config.csp = SecureHeaders::OPT_OUT # If this line is omitted, we will assume you meant to opt out.
config.csp_report_only = {
default_src: %w('self')
}
end
- Rack rack-secure_headers
- Node.js (express) helmet and hood
- Node.js (hapi) blankie
- J2EE Servlet >= 3.0 headlines
- ASP.NET - NWebsec
- Python - django-csp + commonware; django-security
- Go - secureheader
- Elixir secure_headers
- Dropwizard dropwizard-web-security
- Ember.js ember-cli-content-security-policy
Copyright 2013-2014 Twitter, Inc and other contributors.
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0