Module: SecureHeaders

Included in:
ActionController::Base
Defined in:
lib/secure_headers.rb,
lib/secure_headers/railtie.rb,
lib/secure_headers/middleware.rb,
lib/secure_headers/view_helper.rb,
lib/secure_headers/configuration.rb,
lib/secure_headers/headers/public_key_pins.rb,
lib/secure_headers/headers/x_frame_options.rb,
lib/secure_headers/headers/x_xss_protection.rb,
lib/secure_headers/headers/policy_management.rb,
lib/secure_headers/headers/x_download_options.rb,
lib/secure_headers/headers/x_content_type_options.rb,
lib/secure_headers/headers/content_security_policy.rb,
lib/secure_headers/headers/strict_transport_security.rb,
lib/secure_headers/headers/x_permitted_cross_domain_policies.rb

Overview

All headers (except for hpkp) have a default value. Provide SecureHeaders::OPT_OUT or “:optout_of_protection” as a config value to disable a given header

Defined Under Namespace

Modules: PolicyManagement, ViewHelpers Classes: Configuration, ContentSecurityPolicy, ContentSecurityPolicyConfigError, Middleware, PublicKeyPins, PublicKeyPinsConfigError, Railtie, STSConfigError, StrictTransportSecurity, XContentTypeOptions, XContentTypeOptionsConfigError, XDOConfigError, XDownloadOptions, XFOConfigError, XFrameOptions, XPCDPConfigError, XPermittedCrossDomainPolicies, XXssProtection, XXssProtectionConfigError

Constant Summary collapse

OPT_OUT =
:opt_out_of_protection
SECURE_HEADERS_CONFIG =
"secure_headers_request_config".freeze
NONCE_KEY =
"secure_headers_content_security_policy_nonce".freeze
HTTPS =
"https".freeze
CSP =
ContentSecurityPolicy
ALL_HEADER_CLASSES =
[
  ContentSecurityPolicy,
  StrictTransportSecurity,
  PublicKeyPins,
  XContentTypeOptions,
  XDownloadOptions,
  XFrameOptions,
  XPermittedCrossDomainPolicies,
  XXssProtection
].freeze
ALL_HEADERS_BESIDES_CSP =
(ALL_HEADER_CLASSES - [CSP]).freeze
HTTP_HEADER_CLASSES =

Headers set on http requests (excludes STS and HPKP)

(ALL_HEADER_CLASSES - [StrictTransportSecurity, PublicKeyPins]).freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.append_content_security_policy_directives(request, additions) ⇒ Object

Public: appends source values to the current configuration. If no value is set for a given directive, the value will be merged with the default-src value. If a value exists for the given directive, the values will be combined.

additions - a hash containing directives. e.g.

script_src: %w(another-host.com)


65
66
67
68
69
# File 'lib/secure_headers.rb', line 65

def append_content_security_policy_directives(request, additions)
  config = config_for(request)
  config.dynamic_csp = CSP.combine_policies(config.current_csp, additions)
  override_secure_headers_request_config(request, config)
end

.config_for(request) ⇒ Object

Public: Retreives the config for a given header type:

Checks to see if there is an override for this request, then Checks to see if a named override is used for this request, then Falls back to the global config



149
150
151
152
153
154
155
156
157
158
# File 'lib/secure_headers.rb', line 149

def config_for(request)
  config = request.env[SECURE_HEADERS_CONFIG] ||
    Configuration.get(Configuration::DEFAULT_CONFIG)

  if config.frozen?
    config.dup
  else
    config
  end
end

.content_security_policy_script_nonce(request) ⇒ Object

Public: gets or creates a nonce for CSP.

The nonce will be added to script_src

Returns the nonce



131
132
133
# File 'lib/secure_headers.rb', line 131

def content_security_policy_script_nonce(request)
  content_security_policy_nonce(request, CSP::SCRIPT_SRC)
end

.content_security_policy_style_nonce(request) ⇒ Object

Public: gets or creates a nonce for CSP.

The nonce will be added to style_src

Returns the nonce



140
141
142
# File 'lib/secure_headers.rb', line 140

def content_security_policy_style_nonce(request)
  content_security_policy_nonce(request, CSP::STYLE_SRC)
end

.header_hash_for(request) ⇒ Object

Public: Builds the hash of headers that should be applied base on the request.

StrictTransportSecurity and PublicKeyPins are not applied to http requests. See #config_for to determine which config is used for a given request.

Returns a hash of header names => header values. The value returned is meant to be merged into the header value from ‘@app.call(env)` in Rack middleware.



105
106
107
108
109
110
111
112
# File 'lib/secure_headers.rb', line 105

def header_hash_for(request)
  config = config_for(request)
  unless ContentSecurityPolicy.idempotent_additions?(config.csp, config.current_csp)
    config.rebuild_csp_header_cache!(request.user_agent)
  end

  use_cached_headers(config.cached_headers, request)
end

.opt_out_of_all_protection(request) ⇒ Object

Public: opts out of setting all headers by telling secure_headers to use the NOOP configuration.



92
93
94
# File 'lib/secure_headers.rb', line 92

def opt_out_of_all_protection(request)
  use_secure_headers_override(request, Configuration::NOOP_CONFIGURATION)
end

.opt_out_of_header(request, header_key) ⇒ Object

Public: opts out of setting a given header by creating a temporary config and setting the given headers config to OPT_OUT.



84
85
86
87
88
# File 'lib/secure_headers.rb', line 84

def opt_out_of_header(request, header_key)
  config = config_for(request)
  config.opt_out(header_key)
  override_secure_headers_request_config(request, config)
end

.override_content_security_policy_directives(request, additions) ⇒ Object

Public: override a given set of directives for the current request. If a value already exists for a given directive, it will be overridden.

If CSP was previously OPT_OUT, a new blank policy is used.

additions - a hash containing directives. e.g.

script_src: %w(another-host.com)


49
50
51
52
53
54
55
56
57
# File 'lib/secure_headers.rb', line 49

def override_content_security_policy_directives(request, additions)
  config = config_for(request)
  if config.current_csp == OPT_OUT
    config.dynamic_csp = {}
  end

  config.dynamic_csp = config.current_csp.merge(additions)
  override_secure_headers_request_config(request, config)
end

.override_x_frame_options(request, value) ⇒ Object

Public: override X-Frame-Options settings for this request.

value - deny, sameorigin, or allowall

Returns the current config



76
77
78
79
80
# File 'lib/secure_headers.rb', line 76

def override_x_frame_options(request, value)
  config = config_for(request)
  config.update_x_frame_options(value)
  override_secure_headers_request_config(request, config)
end

.use_secure_headers_override(request, name) ⇒ Object

Public: specify which named override will be used for this request. Raises an argument error if no named override exists.

name - the name of the previously configured override.



118
119
120
121
122
123
124
# File 'lib/secure_headers.rb', line 118

def use_secure_headers_override(request, name)
  if config = Configuration.get(name)
    override_secure_headers_request_config(request, config)
  else
    raise ArgumentError.new("no override by the name of #{name} has been configured")
  end
end

Instance Method Details

#append_content_security_policy_directives(additions) ⇒ Object



255
256
257
# File 'lib/secure_headers.rb', line 255

def append_content_security_policy_directives(additions)
  SecureHeaders.append_content_security_policy_directives(request, additions)
end

#content_security_policy_script_nonceObject



243
244
245
# File 'lib/secure_headers.rb', line 243

def content_security_policy_script_nonce
  SecureHeaders.content_security_policy_script_nonce(request)
end

#content_security_policy_style_nonceObject



247
248
249
# File 'lib/secure_headers.rb', line 247

def content_security_policy_style_nonce
  SecureHeaders.content_security_policy_style_nonce(request)
end

#opt_out_of_header(header_key) ⇒ Object



251
252
253
# File 'lib/secure_headers.rb', line 251

def opt_out_of_header(header_key)
  SecureHeaders.opt_out_of_header(request, header_key)
end

#override_content_security_policy_directives(additions) ⇒ Object



259
260
261
# File 'lib/secure_headers.rb', line 259

def override_content_security_policy_directives(additions)
  SecureHeaders.override_content_security_policy_directives(request, additions)
end

#override_x_frame_options(value) ⇒ Object



263
264
265
# File 'lib/secure_headers.rb', line 263

def override_x_frame_options(value)
  SecureHeaders.override_x_frame_options(request, value)
end

#use_secure_headers_override(name) ⇒ Object

These methods are mixed into controllers and delegate to the class method with the same name.



239
240
241
# File 'lib/secure_headers.rb', line 239

def use_secure_headers_override(name)
  SecureHeaders.use_secure_headers_override(request, name)
end