secure_headers 5.2.0 → 6.0.0.alpha01
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.
Potentially problematic release.
This version of secure_headers might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +8 -4
- data/CHANGELOG.md +3 -7
- data/Gemfile +1 -1
- data/docs/upgrading-to-6-0.md +50 -0
- data/lib/secure_headers.rb +14 -76
- data/lib/secure_headers/configuration.rb +114 -164
- data/lib/secure_headers/headers/clear_site_data.rb +1 -3
- data/lib/secure_headers/headers/content_security_policy.rb +4 -17
- data/lib/secure_headers/headers/content_security_policy_config.rb +3 -13
- data/lib/secure_headers/headers/expect_certificate_transparency.rb +2 -3
- data/lib/secure_headers/headers/policy_management.rb +12 -11
- data/lib/secure_headers/headers/public_key_pins.rb +2 -3
- data/lib/secure_headers/headers/referrer_policy.rb +2 -2
- data/lib/secure_headers/headers/strict_transport_security.rb +2 -2
- data/lib/secure_headers/headers/x_content_type_options.rb +2 -2
- data/lib/secure_headers/headers/x_download_options.rb +2 -2
- data/lib/secure_headers/headers/x_frame_options.rb +1 -2
- data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +2 -2
- data/lib/secure_headers/headers/x_xss_protection.rb +3 -3
- data/secure_headers.gemspec +1 -1
- data/spec/lib/secure_headers/configuration_spec.rb +15 -70
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +12 -22
- data/spec/lib/secure_headers/headers/policy_management_spec.rb +33 -7
- data/spec/lib/secure_headers/middleware_spec.rb +7 -1
- data/spec/lib/secure_headers/view_helpers_spec.rb +1 -0
- data/spec/lib/secure_headers_spec.rb +39 -40
- data/spec/spec_helper.rb +7 -3
- metadata +5 -4
@@ -11,13 +11,11 @@ module SecureHeaders
|
|
11
11
|
EXECUTION_CONTEXTS = "executionContexts".freeze
|
12
12
|
ALL_TYPES = [CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS]
|
13
13
|
|
14
|
-
CONFIG_KEY = :clear_site_data
|
15
|
-
|
16
14
|
class << self
|
17
15
|
# Public: make an Clear-Site-Data header name, value pair
|
18
16
|
#
|
19
17
|
# Returns nil if not configured, returns header name and value if configured.
|
20
|
-
def make_header(config = nil)
|
18
|
+
def make_header(config = nil, user_agent = nil)
|
21
19
|
case config
|
22
20
|
when nil, OPT_OUT, []
|
23
21
|
# noop
|
@@ -13,6 +13,7 @@ module SecureHeaders
|
|
13
13
|
FALLBACK_VERSION = ::UserAgent::Version.new("0")
|
14
14
|
|
15
15
|
def initialize(config = nil, user_agent = OTHER)
|
16
|
+
user_agent ||= OTHER
|
16
17
|
@config = if config.is_a?(Hash)
|
17
18
|
if config[:report_only]
|
18
19
|
ContentSecurityPolicyReportOnlyConfig.new(config || DEFAULT_CONFIG)
|
@@ -138,14 +139,8 @@ module SecureHeaders
|
|
138
139
|
end
|
139
140
|
|
140
141
|
if source_list != OPT_OUT && source_list && source_list.any?
|
141
|
-
|
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
|
142
|
+
normalized_source_list = minify_source_list(directive, source_list)
|
143
|
+
[symbol_to_hyphen_case(directive), normalized_source_list].join(" ")
|
149
144
|
end
|
150
145
|
end
|
151
146
|
|
@@ -218,11 +213,7 @@ module SecureHeaders
|
|
218
213
|
# unsafe-inline, this is more concise.
|
219
214
|
def append_nonce(source_list, nonce)
|
220
215
|
if nonce
|
221
|
-
|
222
|
-
source_list << "'nonce-#{nonce}'"
|
223
|
-
else
|
224
|
-
source_list << UNSAFE_INLINE
|
225
|
-
end
|
216
|
+
source_list.push("'nonce-#{nonce}'", UNSAFE_INLINE)
|
226
217
|
end
|
227
218
|
|
228
219
|
source_list
|
@@ -262,10 +253,6 @@ module SecureHeaders
|
|
262
253
|
end
|
263
254
|
end
|
264
255
|
|
265
|
-
def nonces_supported?
|
266
|
-
@nonces_supported ||= self.class.nonces_supported?(@parsed_ua)
|
267
|
-
end
|
268
|
-
|
269
256
|
def symbol_to_hyphen_case(sym)
|
270
257
|
sym.to_s.tr("_", "-")
|
271
258
|
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
|
-
|
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'),
|
@@ -200,7 +199,8 @@ module SecureHeaders
|
|
200
199
|
#
|
201
200
|
# Returns a default policy if no configuration is provided, or a
|
202
201
|
# header name and value based on the config.
|
203
|
-
def make_header(config, user_agent)
|
202
|
+
def make_header(config, user_agent = nil)
|
203
|
+
return if config.nil? || config == OPT_OUT
|
204
204
|
header = new(config, user_agent)
|
205
205
|
[header.name, header.value]
|
206
206
|
end
|
@@ -215,27 +215,28 @@ module SecureHeaders
|
|
215
215
|
if config.directive_value(:script_src).nil?
|
216
216
|
raise ContentSecurityPolicyConfigError.new(":script_src is required, falling back to default-src is too dangerous. Use `script_src: OPT_OUT` to override")
|
217
217
|
end
|
218
|
+
if !config.report_only? && config.directive_value(:report_only)
|
219
|
+
raise ContentSecurityPolicyConfigError.new("Only the csp_report_only config should set :report_only to true")
|
220
|
+
end
|
221
|
+
|
222
|
+
if config.report_only? && config.directive_value(:report_only) == false
|
223
|
+
raise ContentSecurityPolicyConfigError.new("csp_report_only config must have :report_only set to true")
|
224
|
+
end
|
218
225
|
|
219
226
|
ContentSecurityPolicyConfig.attrs.each do |key|
|
220
227
|
value = config.directive_value(key)
|
221
228
|
next unless value
|
229
|
+
|
222
230
|
if META_CONFIGS.include?(key)
|
223
231
|
raise ContentSecurityPolicyConfigError.new("#{key} must be a boolean value") unless boolean?(value) || value.nil?
|
232
|
+
elsif NONCES.include?(key)
|
233
|
+
raise ContentSecurityPolicyConfigError.new("#{key} must be a non-nil value") if value.nil?
|
224
234
|
else
|
225
235
|
validate_directive!(key, value)
|
226
236
|
end
|
227
237
|
end
|
228
238
|
end
|
229
239
|
|
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
240
|
# Public: combine the values from two different configs.
|
240
241
|
#
|
241
242
|
# original - the main config
|
@@ -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/
|
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
|
|
data/secure_headers.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "secure_headers"
|
5
|
-
gem.version = "
|
5
|
+
gem.version = "6.0.0.alpha01"
|
6
6
|
gem.authors = ["Neil Matatall"]
|
7
7
|
gem.email = ["neil.matatall@gmail.com"]
|
8
8
|
gem.description = "Manages application of security headers with many safe defaults."
|
@@ -5,88 +5,33 @@ module SecureHeaders
|
|
5
5
|
describe Configuration do
|
6
6
|
before(:each) do
|
7
7
|
reset_config
|
8
|
-
Configuration.default
|
9
8
|
end
|
10
9
|
|
11
10
|
it "has a default config" do
|
12
|
-
expect(Configuration.
|
13
|
-
end
|
14
|
-
|
15
|
-
it "warns when using deprecated internal-ish #get API" do
|
16
|
-
expect(Kernel).to receive(:warn).once.with(/`#get` is deprecated/)
|
17
|
-
Configuration.get(Configuration::DEFAULT_CONFIG)
|
18
|
-
end
|
19
|
-
|
20
|
-
it "has an 'noop' config" do
|
21
|
-
expect(Configuration.get(Configuration::NOOP_CONFIGURATION, internal: true)).to_not be_nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it "precomputes headers upon creation" do
|
25
|
-
default_config = Configuration.get(Configuration::DEFAULT_CONFIG, internal: true)
|
26
|
-
header_hash = default_config.cached_headers.each_with_object({}) do |(key, value), hash|
|
27
|
-
header_name, header_value = if key == :csp
|
28
|
-
value["Chrome"]
|
29
|
-
else
|
30
|
-
value
|
31
|
-
end
|
32
|
-
|
33
|
-
hash[header_name] = header_value
|
34
|
-
end
|
35
|
-
expect_default_values(header_hash)
|
11
|
+
expect(Configuration.default).to_not be_nil
|
36
12
|
end
|
37
13
|
|
38
|
-
it "
|
39
|
-
Configuration.
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
config = Configuration.get(:test_override, internal: true)
|
44
|
-
noop = Configuration.get(Configuration::NOOP_CONFIGURATION, internal: true)
|
45
|
-
[:csp, :csp_report_only, :cookies].each do |key|
|
46
|
-
expect(config.send(key)).to eq(noop.send(key))
|
47
|
-
end
|
14
|
+
it "has an 'noop' override" do
|
15
|
+
Configuration.default
|
16
|
+
expect(Configuration.overrides(Configuration::NOOP_OVERRIDE)).to_not be_nil
|
48
17
|
end
|
49
18
|
|
50
|
-
it "
|
51
|
-
Configuration.
|
52
|
-
|
19
|
+
it "dup results in a copy of the default config" do
|
20
|
+
Configuration.default
|
21
|
+
original_configuration = Configuration.send(:default_config)
|
22
|
+
configuration = Configuration.dup
|
23
|
+
expect(original_configuration).not_to be(configuration)
|
24
|
+
Configuration::CONFIG_ATTRIBUTES.each do |attr|
|
25
|
+
expect(original_configuration.send(attr)).to eq(configuration.send(attr))
|
53
26
|
end
|
54
|
-
|
55
|
-
expect(Configuration.get(Configuration::DEFAULT_CONFIG, internal: true).cached_headers).to_not eq(Configuration.get(:test_override, internal: true).cached_headers)
|
56
27
|
end
|
57
28
|
|
58
|
-
it "stores an override
|
29
|
+
it "stores an override" do
|
59
30
|
Configuration.override(:test_override) do |config|
|
60
31
|
config.x_frame_options = "DENY"
|
61
32
|
end
|
62
33
|
|
63
|
-
expect(Configuration.
|
64
|
-
end
|
65
|
-
|
66
|
-
it "deep dup's config values when overriding so the original cannot be modified" do
|
67
|
-
Configuration.override(:override) do |config|
|
68
|
-
config.csp[:default_src] << "'self'"
|
69
|
-
end
|
70
|
-
|
71
|
-
default = Configuration.get(Configuration::DEFAULT_CONFIG, internal: true)
|
72
|
-
override = Configuration.get(:override, internal: true)
|
73
|
-
|
74
|
-
expect(override.csp.directive_value(:default_src)).not_to be(default.csp.directive_value(:default_src))
|
75
|
-
end
|
76
|
-
|
77
|
-
it "allows you to override an override" do
|
78
|
-
Configuration.override(:override) do |config|
|
79
|
-
config.csp = { default_src: %w('self'), script_src: %w('self')}
|
80
|
-
end
|
81
|
-
|
82
|
-
Configuration.override(:second_override, :override) do |config|
|
83
|
-
config.csp = config.csp.merge(script_src: %w(example.org))
|
84
|
-
end
|
85
|
-
|
86
|
-
original_override = Configuration.get(:override, internal: true)
|
87
|
-
expect(original_override.csp.to_h).to eq(default_src: %w('self'), script_src: %w('self'))
|
88
|
-
override_config = Configuration.get(:second_override, internal: true)
|
89
|
-
expect(override_config.csp.to_h).to eq(default_src: %w('self'), script_src: %w('self' example.org))
|
34
|
+
expect(Configuration.overrides(:test_override)).to_not be_nil
|
90
35
|
end
|
91
36
|
|
92
37
|
it "deprecates the secure_cookies configuration" do
|
@@ -106,7 +51,7 @@ module SecureHeaders
|
|
106
51
|
config.cookies = OPT_OUT
|
107
52
|
end
|
108
53
|
|
109
|
-
config = Configuration.
|
54
|
+
config = Configuration.dup
|
110
55
|
expect(config.cookies).to eq(OPT_OUT)
|
111
56
|
end
|
112
57
|
|
@@ -115,7 +60,7 @@ module SecureHeaders
|
|
115
60
|
config.cookies = {httponly: true, secure: true, samesite: {lax: false}}
|
116
61
|
end
|
117
62
|
|
118
|
-
config = Configuration.
|
63
|
+
config = Configuration.dup
|
119
64
|
expect(config.cookies).to eq({httponly: true, secure: true, samesite: {lax: false}})
|
120
65
|
end
|
121
66
|
end
|