secure_headers 5.2.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -4
  3. data/CHANGELOG.md +3 -7
  4. data/Gemfile +1 -1
  5. data/README.md +2 -2
  6. data/docs/upgrading-to-6-0.md +50 -0
  7. data/lib/secure_headers/configuration.rb +114 -164
  8. data/lib/secure_headers/headers/clear_site_data.rb +1 -3
  9. data/lib/secure_headers/headers/content_security_policy.rb +8 -74
  10. data/lib/secure_headers/headers/content_security_policy_config.rb +3 -13
  11. data/lib/secure_headers/headers/expect_certificate_transparency.rb +2 -3
  12. data/lib/secure_headers/headers/policy_management.rb +14 -65
  13. data/lib/secure_headers/headers/public_key_pins.rb +2 -3
  14. data/lib/secure_headers/headers/referrer_policy.rb +2 -2
  15. data/lib/secure_headers/headers/strict_transport_security.rb +2 -2
  16. data/lib/secure_headers/headers/x_content_type_options.rb +2 -2
  17. data/lib/secure_headers/headers/x_download_options.rb +2 -2
  18. data/lib/secure_headers/headers/x_frame_options.rb +1 -2
  19. data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +2 -2
  20. data/lib/secure_headers/headers/x_xss_protection.rb +3 -3
  21. data/lib/secure_headers/view_helper.rb +9 -8
  22. data/lib/secure_headers.rb +14 -78
  23. data/secure_headers.gemspec +1 -2
  24. data/spec/lib/secure_headers/configuration_spec.rb +15 -70
  25. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +2 -75
  26. data/spec/lib/secure_headers/headers/policy_management_spec.rb +35 -9
  27. data/spec/lib/secure_headers/middleware_spec.rb +7 -1
  28. data/spec/lib/secure_headers/view_helpers_spec.rb +29 -0
  29. data/spec/lib/secure_headers_spec.rb +38 -76
  30. data/spec/spec_helper.rb +7 -3
  31. metadata +3 -16
@@ -1,18 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
  require_relative "policy_management"
3
3
  require_relative "content_security_policy_config"
4
- require "useragent"
5
4
 
6
5
  module SecureHeaders
7
6
  class ContentSecurityPolicy
8
7
  include PolicyManagement
9
8
 
10
- # constants to be used for version-specific UA sniffing
11
- VERSION_46 = ::UserAgent::Version.new("46")
12
- VERSION_10 = ::UserAgent::Version.new("10")
13
- FALLBACK_VERSION = ::UserAgent::Version.new("0")
14
-
15
- def initialize(config = nil, user_agent = OTHER)
9
+ def initialize(config = nil)
16
10
  @config = if config.is_a?(Hash)
17
11
  if config[:report_only]
18
12
  ContentSecurityPolicyReportOnlyConfig.new(config || DEFAULT_CONFIG)
@@ -25,12 +19,6 @@ module SecureHeaders
25
19
  config
26
20
  end
27
21
 
28
- @parsed_ua = if user_agent.is_a?(UserAgent::Browsers::Base)
29
- user_agent
30
- else
31
- UserAgent.parse(user_agent)
32
- end
33
- @frame_src = normalize_child_frame_src
34
22
  @preserve_schemes = @config.preserve_schemes
35
23
  @script_nonce = @config.script_nonce
36
24
  @style_nonce = @config.style_nonce
@@ -55,20 +43,10 @@ module SecureHeaders
55
43
 
56
44
  private
57
45
 
58
- def normalize_child_frame_src
59
- if @config.frame_src && @config.child_src && @config.frame_src != @config.child_src
60
- raise ArgumentError, "#{Kernel.caller.first}: both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers."
61
- end
62
-
63
- @config.frame_src || @config.child_src
64
- end
65
-
66
46
  # Private: converts the config object into a string representing a policy.
67
47
  # Places default-src at the first directive and report-uri as the last. All
68
48
  # others are presented in alphabetical order.
69
49
  #
70
- # Unsupported directives are filtered based on the user agent.
71
- #
72
50
  # Returns a content security policy header value.
73
51
  def build_value
74
52
  directives.map do |directive_name|
@@ -124,28 +102,11 @@ module SecureHeaders
124
102
  #
125
103
  # Returns a string representing a directive.
126
104
  def build_source_list_directive(directive)
127
- source_list = case directive
128
- when :child_src
129
- if supported_directives.include?(:child_src)
130
- @frame_src
131
- end
132
- when :frame_src
133
- unless supported_directives.include?(:child_src)
134
- @frame_src
135
- end
136
- else
137
- @config.directive_value(directive)
138
- end
105
+ source_list = @config.directive_value(directive)
139
106
 
140
107
  if source_list != OPT_OUT && source_list && source_list.any?
141
- minified_source_list = minify_source_list(directive, source_list).join(" ")
142
-
143
- if minified_source_list =~ /(\n|;)/
144
- Kernel.warn("#{directive} contains a #{$1} in #{minified_source_list.inspect} which will raise an error in future versions. It has been replaced with a blank space.")
145
- end
146
-
147
- escaped_source_list = minified_source_list.gsub(/[\n;]/, " ")
148
- [symbol_to_hyphen_case(directive), escaped_source_list].join(" ").strip
108
+ normalized_source_list = minify_source_list(directive, source_list)
109
+ [symbol_to_hyphen_case(directive), normalized_source_list].join(" ")
149
110
  end
150
111
  end
151
112
 
@@ -218,23 +179,19 @@ module SecureHeaders
218
179
  # unsafe-inline, this is more concise.
219
180
  def append_nonce(source_list, nonce)
220
181
  if nonce
221
- if nonces_supported?
222
- source_list << "'nonce-#{nonce}'"
223
- else
224
- source_list << UNSAFE_INLINE
225
- end
182
+ source_list.push("'nonce-#{nonce}'", UNSAFE_INLINE)
226
183
  end
227
184
 
228
185
  source_list
229
186
  end
230
187
 
231
- # Private: return the list of directives that are supported by the user agent,
188
+ # Private: return the list of directives,
232
189
  # starting with default-src and ending with report-uri.
233
190
  def directives
234
191
  [
235
192
  DEFAULT_SRC,
236
- BODY_DIRECTIVES.select { |key| supported_directives.include?(key) },
237
- REPORT_URI
193
+ BODY_DIRECTIVES,
194
+ REPORT_URI,
238
195
  ].flatten
239
196
  end
240
197
 
@@ -243,29 +200,6 @@ module SecureHeaders
243
200
  source_list.map { |source_expression| source_expression.sub(HTTP_SCHEME_REGEX, "") }
244
201
  end
245
202
 
246
- # Private: determine which directives are supported for the given user agent.
247
- #
248
- # Add UA-sniffing special casing here.
249
- #
250
- # Returns an array of symbols representing the directives.
251
- def supported_directives
252
- @supported_directives ||= if VARIATIONS[@parsed_ua.browser]
253
- if @parsed_ua.browser == "Firefox" && ((@parsed_ua.version || FALLBACK_VERSION) >= VERSION_46)
254
- VARIATIONS["FirefoxTransitional"]
255
- elsif @parsed_ua.browser == "Safari" && ((@parsed_ua.version || FALLBACK_VERSION) >= VERSION_10)
256
- VARIATIONS["SafariTransitional"]
257
- else
258
- VARIATIONS[@parsed_ua.browser]
259
- end
260
- else
261
- VARIATIONS[OTHER]
262
- end
263
- end
264
-
265
- def nonces_supported?
266
- @nonces_supported ||= self.class.nonces_supported?(@parsed_ua)
267
- end
268
-
269
203
  def symbol_to_hyphen_case(sym)
270
204
  sym.to_s.tr("_", "-")
271
205
  end
@@ -2,7 +2,6 @@
2
2
  module SecureHeaders
3
3
  module DynamicConfig
4
4
  def self.included(base)
5
- base.send(:attr_writer, :modified)
6
5
  base.send(:attr_reader, *base.attrs)
7
6
  base.attrs.each do |attr|
8
7
  base.send(:define_method, "#{attr}=") do |value|
@@ -42,7 +41,6 @@ module SecureHeaders
42
41
  @upgrade_insecure_requests = nil
43
42
 
44
43
  from_hash(hash)
45
- @modified = false
46
44
  end
47
45
 
48
46
  def update_directive(directive, value)
@@ -55,12 +53,10 @@ module SecureHeaders
55
53
  end
56
54
  end
57
55
 
58
- def modified?
59
- @modified
60
- end
61
-
62
56
  def merge(new_hash)
63
- ContentSecurityPolicy.combine_policies(self.to_h, new_hash)
57
+ new_config = self.dup
58
+ new_config.send(:from_hash, new_hash)
59
+ new_config
64
60
  end
65
61
 
66
62
  def merge!(new_hash)
@@ -109,17 +105,12 @@ module SecureHeaders
109
105
  def write_attribute(attr, value)
110
106
  value = value.dup if PolicyManagement::DIRECTIVE_VALUE_TYPES[attr] == :source_list
111
107
  attr_variable = "@#{attr}"
112
- prev_value = self.instance_variable_get(attr_variable)
113
108
  self.instance_variable_set(attr_variable, value)
114
- if prev_value != value
115
- @modified = true
116
- end
117
109
  end
118
110
  end
119
111
 
120
112
  class ContentSecurityPolicyConfigError < StandardError; end
121
113
  class ContentSecurityPolicyConfig
122
- CONFIG_KEY = :csp
123
114
  HEADER_NAME = "Content-Security-Policy".freeze
124
115
 
125
116
  ATTRS = PolicyManagement::ALL_DIRECTIVES + PolicyManagement::META_CONFIGS + PolicyManagement::NONCES
@@ -149,7 +140,6 @@ module SecureHeaders
149
140
  end
150
141
 
151
142
  class ContentSecurityPolicyReportOnlyConfig < ContentSecurityPolicyConfig
152
- CONFIG_KEY = :csp_report_only
153
143
  HEADER_NAME = "Content-Security-Policy-Report-Only".freeze
154
144
 
155
145
  def report_only?
@@ -4,7 +4,6 @@ module SecureHeaders
4
4
 
5
5
  class ExpectCertificateTransparency
6
6
  HEADER_NAME = "Expect-CT".freeze
7
- CONFIG_KEY = :expect_certificate_transparency
8
7
  INVALID_CONFIGURATION_ERROR = "config must be a hash.".freeze
9
8
  INVALID_ENFORCE_VALUE_ERROR = "enforce must be a boolean".freeze
10
9
  REQUIRED_MAX_AGE_ERROR = "max-age is a required directive.".freeze
@@ -15,8 +14,8 @@ module SecureHeaders
15
14
  #
16
15
  # Returns nil if not configured, returns header name and value if
17
16
  # configured.
18
- def make_header(config)
19
- return if config.nil?
17
+ def make_header(config, use_agent = nil)
18
+ return if config.nil? || config == OPT_OUT
20
19
 
21
20
  header = new(config)
22
21
  [HEADER_NAME, header.value]
@@ -5,7 +5,6 @@ module SecureHeaders
5
5
  base.extend(ClassMethods)
6
6
  end
7
7
 
8
- MODERN_BROWSERS = %w(Chrome Opera Firefox)
9
8
  DEFAULT_CONFIG = {
10
9
  default_src: %w(https:),
11
10
  img_src: %w(https: data: 'self'),
@@ -82,58 +81,12 @@ module SecureHeaders
82
81
  UPGRADE_INSECURE_REQUESTS
83
82
  ].flatten.freeze
84
83
 
85
- EDGE_DIRECTIVES = DIRECTIVES_1_0
86
- SAFARI_DIRECTIVES = DIRECTIVES_1_0
87
- SAFARI_10_DIRECTIVES = DIRECTIVES_2_0
88
-
89
- FIREFOX_UNSUPPORTED_DIRECTIVES = [
90
- BLOCK_ALL_MIXED_CONTENT,
91
- CHILD_SRC,
92
- WORKER_SRC,
93
- PLUGIN_TYPES
94
- ].freeze
95
-
96
- FIREFOX_46_DEPRECATED_DIRECTIVES = [
97
- FRAME_SRC
98
- ].freeze
99
-
100
- FIREFOX_46_UNSUPPORTED_DIRECTIVES = [
101
- BLOCK_ALL_MIXED_CONTENT,
102
- WORKER_SRC,
103
- PLUGIN_TYPES
104
- ].freeze
105
-
106
- FIREFOX_DIRECTIVES = (
107
- DIRECTIVES_3_0 - FIREFOX_UNSUPPORTED_DIRECTIVES
108
- ).freeze
109
-
110
- FIREFOX_46_DIRECTIVES = (
111
- DIRECTIVES_3_0 - FIREFOX_46_UNSUPPORTED_DIRECTIVES - FIREFOX_46_DEPRECATED_DIRECTIVES
112
- ).freeze
113
-
114
- CHROME_DIRECTIVES = (
115
- DIRECTIVES_3_0
116
- ).freeze
117
-
118
84
  ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0).uniq.sort
119
85
 
120
86
  # Think of default-src and report-uri as the beginning and end respectively,
121
87
  # everything else is in between.
122
88
  BODY_DIRECTIVES = ALL_DIRECTIVES - [DEFAULT_SRC, REPORT_URI]
123
89
 
124
- VARIATIONS = {
125
- "Chrome" => CHROME_DIRECTIVES,
126
- "Opera" => CHROME_DIRECTIVES,
127
- "Firefox" => FIREFOX_DIRECTIVES,
128
- "FirefoxTransitional" => FIREFOX_46_DIRECTIVES,
129
- "Safari" => SAFARI_DIRECTIVES,
130
- "SafariTransitional" => SAFARI_10_DIRECTIVES,
131
- "Edge" => EDGE_DIRECTIVES,
132
- "Other" => CHROME_DIRECTIVES
133
- }.freeze
134
-
135
- OTHER = "Other".freeze
136
-
137
90
  DIRECTIVE_VALUE_TYPES = {
138
91
  BASE_URI => :source_list,
139
92
  BLOCK_ALL_MIXED_CONTENT => :boolean,
@@ -200,8 +153,9 @@ module SecureHeaders
200
153
  #
201
154
  # Returns a default policy if no configuration is provided, or a
202
155
  # header name and value based on the config.
203
- def make_header(config, user_agent)
204
- header = new(config, user_agent)
156
+ def make_header(config)
157
+ return if config.nil? || config == OPT_OUT
158
+ header = new(config)
205
159
  [header.name, header.value]
206
160
  end
207
161
 
@@ -215,27 +169,28 @@ module SecureHeaders
215
169
  if config.directive_value(:script_src).nil?
216
170
  raise ContentSecurityPolicyConfigError.new(":script_src is required, falling back to default-src is too dangerous. Use `script_src: OPT_OUT` to override")
217
171
  end
172
+ if !config.report_only? && config.directive_value(:report_only)
173
+ raise ContentSecurityPolicyConfigError.new("Only the csp_report_only config should set :report_only to true")
174
+ end
175
+
176
+ if config.report_only? && config.directive_value(:report_only) == false
177
+ raise ContentSecurityPolicyConfigError.new("csp_report_only config must have :report_only set to true")
178
+ end
218
179
 
219
180
  ContentSecurityPolicyConfig.attrs.each do |key|
220
181
  value = config.directive_value(key)
221
182
  next unless value
183
+
222
184
  if META_CONFIGS.include?(key)
223
185
  raise ContentSecurityPolicyConfigError.new("#{key} must be a boolean value") unless boolean?(value) || value.nil?
186
+ elsif NONCES.include?(key)
187
+ raise ContentSecurityPolicyConfigError.new("#{key} must be a non-nil value") if value.nil?
224
188
  else
225
189
  validate_directive!(key, value)
226
190
  end
227
191
  end
228
192
  end
229
193
 
230
- # Public: check if a user agent supports CSP nonces
231
- #
232
- # user_agent - a String or a UserAgent object
233
- def nonces_supported?(user_agent)
234
- user_agent = UserAgent.parse(user_agent) if user_agent.is_a?(String)
235
- MODERN_BROWSERS.include?(user_agent.browser) ||
236
- user_agent.browser == "Safari" && (user_agent.version || CSP::FALLBACK_VERSION) >= CSP::VERSION_10
237
- end
238
-
239
194
  # Public: combine the values from two different configs.
240
195
  #
241
196
  # original - the main config
@@ -302,17 +257,11 @@ module SecureHeaders
302
257
  # Don't set a default if directive has an existing value
303
258
  next if original[directive]
304
259
  if FETCH_SOURCES.include?(directive)
305
- original[directive] = default_for(directive, original)
260
+ original[directive] = original[DEFAULT_SRC]
306
261
  end
307
262
  end
308
263
  end
309
264
 
310
- def default_for(directive, original)
311
- return original[FRAME_SRC] if directive == CHILD_SRC && original[FRAME_SRC]
312
- return original[CHILD_SRC] if directive == FRAME_SRC && original[CHILD_SRC]
313
- original[DEFAULT_SRC]
314
- end
315
-
316
265
  def source_list?(directive)
317
266
  DIRECTIVE_VALUE_TYPES[directive] == :source_list
318
267
  end
@@ -5,15 +5,14 @@ module SecureHeaders
5
5
  HEADER_NAME = "Public-Key-Pins".freeze
6
6
  REPORT_ONLY = "Public-Key-Pins-Report-Only".freeze
7
7
  HASH_ALGORITHMS = [:sha256].freeze
8
- CONFIG_KEY = :hpkp
9
8
 
10
9
 
11
10
  class << self
12
11
  # Public: make an hpkp header name, value pair
13
12
  #
14
13
  # Returns nil if not configured, returns header name and value if configured.
15
- def make_header(config)
16
- return if config.nil?
14
+ def make_header(config, user_agent = nil)
15
+ return if config.nil? || config == OPT_OUT
17
16
  header = new(config)
18
17
  [header.name, header.value]
19
18
  end
@@ -14,14 +14,14 @@ module SecureHeaders
14
14
  origin-when-cross-origin
15
15
  unsafe-url
16
16
  )
17
- CONFIG_KEY = :referrer_policy
18
17
 
19
18
  class << self
20
19
  # Public: generate an Referrer Policy header.
21
20
  #
22
21
  # Returns a default header if no configuration is provided, or a
23
22
  # header name and value based on the config.
24
- def make_header(config = nil)
23
+ def make_header(config = nil, user_agent = nil)
24
+ return if config == OPT_OUT
25
25
  config ||= DEFAULT_VALUE
26
26
  [HEADER_NAME, Array(config).join(", ")]
27
27
  end
@@ -8,14 +8,14 @@ module SecureHeaders
8
8
  DEFAULT_VALUE = "max-age=" + HSTS_MAX_AGE
9
9
  VALID_STS_HEADER = /\Amax-age=\d+(; includeSubdomains)?(; preload)?\z/i
10
10
  MESSAGE = "The config value supplied for the HSTS header was invalid. Must match #{VALID_STS_HEADER}"
11
- CONFIG_KEY = :hsts
12
11
 
13
12
  class << self
14
13
  # Public: generate an hsts header name, value pair.
15
14
  #
16
15
  # Returns a default header if no configuration is provided, or a
17
16
  # header name and value based on the config.
18
- def make_header(config = nil)
17
+ def make_header(config = nil, user_agent = nil)
18
+ return if config == OPT_OUT
19
19
  [HEADER_NAME, config || DEFAULT_VALUE]
20
20
  end
21
21
 
@@ -5,14 +5,14 @@ module SecureHeaders
5
5
  class XContentTypeOptions
6
6
  HEADER_NAME = "X-Content-Type-Options".freeze
7
7
  DEFAULT_VALUE = "nosniff"
8
- CONFIG_KEY = :x_content_type_options
9
8
 
10
9
  class << self
11
10
  # Public: generate an X-Content-Type-Options header.
12
11
  #
13
12
  # Returns a default header if no configuration is provided, or a
14
13
  # header name and value based on the config.
15
- def make_header(config = nil)
14
+ def make_header(config = nil, user_agent = nil)
15
+ return if config == OPT_OUT
16
16
  [HEADER_NAME, config || DEFAULT_VALUE]
17
17
  end
18
18
 
@@ -4,14 +4,14 @@ module SecureHeaders
4
4
  class XDownloadOptions
5
5
  HEADER_NAME = "X-Download-Options".freeze
6
6
  DEFAULT_VALUE = "noopen"
7
- CONFIG_KEY = :x_download_options
8
7
 
9
8
  class << self
10
9
  # Public: generate an X-Download-Options header.
11
10
  #
12
11
  # Returns a default header if no configuration is provided, or a
13
12
  # header name and value based on the config.
14
- def make_header(config = nil)
13
+ def make_header(config = nil, user_agent = nil)
14
+ return if config == OPT_OUT
15
15
  [HEADER_NAME, config || DEFAULT_VALUE]
16
16
  end
17
17
 
@@ -3,7 +3,6 @@ module SecureHeaders
3
3
  class XFOConfigError < StandardError; end
4
4
  class XFrameOptions
5
5
  HEADER_NAME = "X-Frame-Options".freeze
6
- CONFIG_KEY = :x_frame_options
7
6
  SAMEORIGIN = "sameorigin"
8
7
  DENY = "deny"
9
8
  ALLOW_FROM = "allow-from"
@@ -16,7 +15,7 @@ module SecureHeaders
16
15
  #
17
16
  # Returns a default header if no configuration is provided, or a
18
17
  # header name and value based on the config.
19
- def make_header(config = nil)
18
+ def make_header(config = nil, user_agent = nil)
20
19
  return if config == OPT_OUT
21
20
  [HEADER_NAME, config || DEFAULT_VALUE]
22
21
  end
@@ -5,14 +5,14 @@ module SecureHeaders
5
5
  HEADER_NAME = "X-Permitted-Cross-Domain-Policies".freeze
6
6
  DEFAULT_VALUE = "none"
7
7
  VALID_POLICIES = %w(all none master-only by-content-type by-ftp-filename)
8
- CONFIG_KEY = :x_permitted_cross_domain_policies
9
8
 
10
9
  class << self
11
10
  # Public: generate an X-Permitted-Cross-Domain-Policies header.
12
11
  #
13
12
  # Returns a default header if no configuration is provided, or a
14
13
  # header name and value based on the config.
15
- def make_header(config = nil)
14
+ def make_header(config = nil, user_agent = nil)
15
+ return if config == OPT_OUT
16
16
  [HEADER_NAME, config || DEFAULT_VALUE]
17
17
  end
18
18
 
@@ -4,15 +4,15 @@ module SecureHeaders
4
4
  class XXssProtection
5
5
  HEADER_NAME = "X-XSS-Protection".freeze
6
6
  DEFAULT_VALUE = "1; mode=block"
7
- VALID_X_XSS_HEADER = /\A[01](; mode=block)?(; report=.*)?\z/i
8
- CONFIG_KEY = :x_xss_protection
7
+ VALID_X_XSS_HEADER = /\A[01](; mode=block)?(; report=.*)?\z/
9
8
 
10
9
  class << self
11
10
  # Public: generate an X-Xss-Protection header.
12
11
  #
13
12
  # Returns a default header if no configuration is provided, or a
14
13
  # header name and value based on the config.
15
- def make_header(config = nil)
14
+ def make_header(config = nil, user_agent = nil)
15
+ return if config == OPT_OUT
16
16
  [HEADER_NAME, config || DEFAULT_VALUE]
17
17
  end
18
18
 
@@ -19,7 +19,7 @@ module SecureHeaders
19
19
  #
20
20
  # Returns an html-safe link tag with the nonce attribute.
21
21
  def nonced_stylesheet_link_tag(*args, &block)
22
- opts = extract_options(args).merge(nonce: content_security_policy_nonce(:style))
22
+ opts = extract_options(args).merge(nonce: _content_security_policy_nonce(:style))
23
23
 
24
24
  stylesheet_link_tag(*args, opts, &block)
25
25
  end
@@ -37,7 +37,7 @@ module SecureHeaders
37
37
  #
38
38
  # Returns an html-safe script tag with the nonce attribute.
39
39
  def nonced_javascript_include_tag(*args, &block)
40
- opts = extract_options(args).merge(nonce: content_security_policy_nonce(:script))
40
+ opts = extract_options(args).merge(nonce: _content_security_policy_nonce(:script))
41
41
 
42
42
  javascript_include_tag(*args, opts, &block)
43
43
  end
@@ -47,7 +47,7 @@ module SecureHeaders
47
47
  #
48
48
  # Returns an html-safe script tag with the nonce attribute.
49
49
  def nonced_javascript_pack_tag(*args, &block)
50
- opts = extract_options(args).merge(nonce: content_security_policy_nonce(:script))
50
+ opts = extract_options(args).merge(nonce: _content_security_policy_nonce(:script))
51
51
 
52
52
  javascript_pack_tag(*args, opts, &block)
53
53
  end
@@ -57,7 +57,7 @@ module SecureHeaders
57
57
  #
58
58
  # Returns an html-safe link tag with the nonce attribute.
59
59
  def nonced_stylesheet_pack_tag(*args, &block)
60
- opts = extract_options(args).merge(nonce: content_security_policy_nonce(:style))
60
+ opts = extract_options(args).merge(nonce: _content_security_policy_nonce(:style))
61
61
 
62
62
  stylesheet_pack_tag(*args, opts, &block)
63
63
  end
@@ -66,7 +66,7 @@ module SecureHeaders
66
66
  # Instructs secure_headers to append a nonce to style/script-src directives.
67
67
  #
68
68
  # Returns a non-html-safe nonce value.
69
- def content_security_policy_nonce(type)
69
+ def _content_security_policy_nonce(type)
70
70
  case type
71
71
  when :script
72
72
  SecureHeaders.content_security_policy_script_nonce(@_request)
@@ -74,13 +74,14 @@ module SecureHeaders
74
74
  SecureHeaders.content_security_policy_style_nonce(@_request)
75
75
  end
76
76
  end
77
+ alias_method :content_security_policy_nonce, :_content_security_policy_nonce
77
78
 
78
79
  def content_security_policy_script_nonce
79
- content_security_policy_nonce(:script)
80
+ _content_security_policy_nonce(:script)
80
81
  end
81
82
 
82
83
  def content_security_policy_style_nonce
83
- content_security_policy_nonce(:style)
84
+ _content_security_policy_nonce(:style)
84
85
  end
85
86
 
86
87
  ##
@@ -152,7 +153,7 @@ module SecureHeaders
152
153
  else
153
154
  content_or_options.html_safe # :'(
154
155
  end
155
- content_tag type, content, options.merge(nonce: content_security_policy_nonce(type))
156
+ content_tag type, content, options.merge(nonce: _content_security_policy_nonce(type))
156
157
  end
157
158
 
158
159
  def extract_options(args)