Module: SecureHeaders

Included in:
ActionController::Base
Defined in:
lib/secure_headers.rb,
lib/secure_headers/railtie.rb,
lib/secure_headers/version.rb,
lib/secure_headers/middleware.rb,
lib/secure_headers/hash_helper.rb,
lib/secure_headers/view_helper.rb,
lib/secure_headers/configuration.rb,
lib/secure_headers/headers/cookie.rb,
lib/secure_headers/utils/cookies_config.rb,
lib/secure_headers/headers/clear_site_data.rb,
lib/secure_headers/headers/referrer_policy.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/content_security_policy_config.rb,
lib/secure_headers/headers/expect_certificate_transparency.rb,
lib/secure_headers/headers/x_permitted_cross_domain_policies.rb

Overview

Provide SecureHeaders::OPT_OUT as a config value to disable a given header

Defined Under Namespace

Modules: DynamicConfig, HashHelper, PolicyManagement, ViewHelpers Classes: ClearSiteData, ClearSiteDataConfigError, Configuration, ContentSecurityPolicy, ContentSecurityPolicyConfig, ContentSecurityPolicyConfigError, ContentSecurityPolicyReportOnlyConfig, Cookie, CookiesConfig, CookiesConfigError, ExpectCertificateTransparency, ExpectCertificateTransparencyConfigError, Middleware, NoOpHeaderConfig, Railtie, ReferrerPolicy, ReferrerPolicyConfigError, STSConfigError, StrictTransportSecurity, XContentTypeOptions, XContentTypeOptionsConfigError, XDOConfigError, XDownloadOptions, XFOConfigError, XFrameOptions, XPCDPConfigError, XPermittedCrossDomainPolicies, XXssProtection, XXssProtectionConfigError

Constant Summary collapse

OPT_OUT =
NoOpHeaderConfig.instance
SECURE_HEADERS_CONFIG =
"secure_headers_request_config".freeze
NONCE_KEY =
"secure_headers_content_security_policy_nonce".freeze
HTTPS =
"https".freeze
CSP =
ContentSecurityPolicy
VERSION =
"7.0.0"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.append_content_security_policy_directives(request, additions, target = nil) ⇒ 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)


88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/secure_headers.rb', line 88

def append_content_security_policy_directives(request, additions, target = nil)
  config, target = config_and_target(request, target)

  if [:both, :enforced].include?(target) && !config.csp.opt_out?
    config.csp.append(additions)
  end

  if [:both, :report_only].include?(target) && !config.csp_report_only.opt_out?
    config.csp_report_only.append(additions)
  end

  override_secure_headers_request_config(request, config)
end

.config_for(request, prevent_dup = false) ⇒ 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



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/secure_headers.rb', line 186

def config_for(request, prevent_dup = false)
  config = request.env[SECURE_HEADERS_CONFIG] ||
    Configuration.send(:default_config)


  # Global configs are frozen, per-request configs are not. When we're not
  # making modifications to the config, prevent_dup ensures we don't dup
  # the object unnecessarily. It's not necessarily frozen to begin with.
  if config.frozen? && !prevent_dup
    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



168
169
170
# File 'lib/secure_headers.rb', line 168

def content_security_policy_script_nonce(request)
  content_security_policy_nonce(request, ContentSecurityPolicy::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



177
178
179
# File 'lib/secure_headers.rb', line 177

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

.header_hash_for(request) ⇒ Object

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

StrictTransportSecurity is 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.



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/secure_headers.rb', line 141

def header_hash_for(request)
  prevent_dup = true
  config = config_for(request, prevent_dup)
  config.validate_config!
  headers = config.generate_headers

  if request.scheme != HTTPS
    headers.delete(StrictTransportSecurity::HEADER_NAME)
  end
  headers
end

.opt_out_of_all_protection(request) ⇒ Object

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



128
129
130
# File 'lib/secure_headers.rb', line 128

def opt_out_of_all_protection(request)
  use_secure_headers_override(request, Configuration::NOOP_OVERRIDE)
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.



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

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, target = nil) ⇒ 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)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/secure_headers.rb', line 60

def override_content_security_policy_directives(request, additions, target = nil)
  config, target = config_and_target(request, target)

  if [:both, :enforced].include?(target)
    if config.csp.opt_out?
      config.csp = ContentSecurityPolicyConfig.new({})
    end

    config.csp.merge!(additions)
  end

  if [:both, :report_only].include?(target)
    if config.csp_report_only.opt_out?
      config.csp_report_only = ContentSecurityPolicyReportOnlyConfig.new({})
    end

    config.csp_report_only.merge!(additions)
  end

  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



112
113
114
115
116
# File 'lib/secure_headers.rb', line 112

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_content_security_policy_named_append(request, name) ⇒ Object



102
103
104
105
# File 'lib/secure_headers.rb', line 102

def use_content_security_policy_named_append(request, name)
  additions = SecureHeaders::Configuration.named_appends(name).call(request)
  append_content_security_policy_directives(request, additions)
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.



157
158
159
160
161
# File 'lib/secure_headers.rb', line 157

def use_secure_headers_override(request, name)
  config = config_for(request)
  config.override(name)
  override_secure_headers_request_config(request, config)
end

Instance Method Details

#append_content_security_policy_directives(additions) ⇒ Object



265
266
267
# File 'lib/secure_headers.rb', line 265

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

#content_security_policy_script_nonceObject



253
254
255
# File 'lib/secure_headers.rb', line 253

def content_security_policy_script_nonce
  SecureHeaders.content_security_policy_script_nonce(request)
end

#content_security_policy_style_nonceObject



257
258
259
# File 'lib/secure_headers.rb', line 257

def content_security_policy_style_nonce
  SecureHeaders.content_security_policy_style_nonce(request)
end

#opt_out_of_header(header_key) ⇒ Object



261
262
263
# File 'lib/secure_headers.rb', line 261

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

#override_content_security_policy_directives(additions) ⇒ Object



269
270
271
# File 'lib/secure_headers.rb', line 269

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

#override_x_frame_options(value) ⇒ Object



273
274
275
# File 'lib/secure_headers.rb', line 273

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

#use_content_security_policy_named_append(name) ⇒ Object



277
278
279
# File 'lib/secure_headers.rb', line 277

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

#use_secure_headers_override(name) ⇒ Object

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



249
250
251
# File 'lib/secure_headers.rb', line 249

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