| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
main branch represents 7.x line. See the upgrading to 4.x doc, upgrading to 5.x doc, upgrading to 6.x doc or upgrading to 7.x doc for instructions on how to upgrade. Bug fixes should go in the 6.x branch for now.
The gem will automatically apply several headers that are related to security. This includes:
It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes. This is on default but can be turned off by using config.cookies = SecureHeaders::OPT_OUT.
secure_headers is a library with a global config, per request overrides, and rack middleware that enables you customize your application settings.
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.
Word of caution: The following is not a default configuration per se. It serves as a sample implementation of the configuration. You should read more about these headers and determine what is appropriate for your requirements.
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=#{1.week.to_i}"
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 = %w(origin-when-cross-origin strict-origin-when-cross-origin)
config.csp = {
# "meta" values. these will shape the header, but the values are not included in the header.
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
disable_nonce_backwards_compatibility: true, # default: false. If false, `unsafe-inline` will be added automatically when using nonces. If true, it won't. See #403 for why you'd want this.
# directive values: these values will directly translate into source directives
default_src: %w('none'),
base_uri: %w('self'),
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:),
manifest_src: %w('self'),
media_src: %w(utoob.com),
object_src: %w('self'),
sandbox: true, # true and [] will set a maximally restrictive setting
plugin_types: %w(application/x-shockwave-flash),
script_src: %w('self'),
script_src_elem: %w('self'),
script_src_attr: %w('self'),
style_src: %w('unsafe-inline'),
style_src_elem: %w('unsafe-inline'),
style_src_attr: %w('unsafe-inline'),
worker_src: %w('self'),
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)
})
# Optional: Use the modern report-to directive (with Reporting-Endpoints header)
config.csp = config.csp.merge({
report_to: "csp-endpoint"
})
# When using report-to, configure the reporting endpoints header
config.reporting_endpoints = {
"csp-endpoint": "https://report-uri.io/example-csp",
"csp-report-only": "https://report-uri.io/example-csp-report-only"
}
endSecureHeaders supports both the legacy report-uri and the modern report-to directives for CSP violation reporting:
The report-uri directive sends violations to a URL endpoint. It's widely supported but limited to POST requests with JSON payloads.
config.csp = {
default_src: %w('self'),
report_uri: %w(https://example.com/csp-report)
}The report-to directive specifies a named reporting endpoint defined in the Reporting-Endpoints header. This enables more flexible reporting through the HTTP Reporting API standard.
config.csp = {
default_src: %w('self'),
report_to: "csp-endpoint"
}
config.reporting_endpoints = {
"csp-endpoint": "https://example.com/reports"
}Recommendation: Use both report-uri and report-to for maximum compatibility while transitioning to the modern approach.
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: 0
Which headers you decide to use for API responses is entirely a personal choice. Things like X-Frame-Options seem to have no place in an API response and would be wasting bytes. While this is true, browsers can do funky things with non-html responses. At the minimum, we suggest CSP:
SecureHeaders::Configuration.override(:api) do |config|
config.csp = { default_src: 'none' }
config.hsts = SecureHeaders::OPT_OUT
config.x_frame_options = SecureHeaders::OPT_OUT
config.x_content_type_options = SecureHeaders::OPT_OUT
config.x_xss_protection = SecureHeaders::OPT_OUT
config.x_permitted_cross_domain_policies = SecureHeaders::OPT_OUT
endHowever, I would consider these headers anyways depending on your load and bandwidth requirements.
If you want to disable secure_headers entirely (e.g., for specific environments or deployment scenarios), you can use Configuration.disable!:
if ENV["ENABLE_STRICT_HEADERS"]
SecureHeaders::Configuration.default do |config|
# your configuration here
end
else
SecureHeaders::Configuration.disable!
endImportant: This configuration must be set during application startup (e.g., in an initializer). Once you call either Configuration.default or Configuration.disable!, the choice cannot be changed at runtime. Attempting to call disable! after default (or vice versa) will raise an AlreadyConfiguredError.
When disabled, no security headers will be set by the gem. This is useful when:
Note: When disable! is used, you don't need to configure a default configuration. The gem will not raise a NotYetConfiguredError.
This project originated within the Security team at Twitter. An archived fork from the point of transition is here: https://github.com/twitter-archive/secure_headers.
Contributors include:
If you've made a contribution and see your name missing from the list, make a PR and add it!
| Back | FazBrowse Home | New Git URL |