secure_headers 5.0.5 → 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.
@@ -17,10 +17,17 @@ module SecureHeaders
17
17
 
18
18
  it "raises a NotYetConfiguredError if trying to opt-out of unconfigured headers" do
19
19
  expect do
20
- SecureHeaders.opt_out_of_header(request, ContentSecurityPolicyConfig::CONFIG_KEY)
20
+ SecureHeaders.opt_out_of_header(request, :csp)
21
21
  end.to raise_error(Configuration::NotYetConfiguredError)
22
22
  end
23
23
 
24
+ it "raises a AlreadyConfiguredError if trying to configure and default has already been set " do
25
+ Configuration.default
26
+ expect do
27
+ Configuration.default
28
+ end.to raise_error(Configuration::AlreadyConfiguredError)
29
+ end
30
+
24
31
  it "raises and ArgumentError when referencing an override that has not been set" do
25
32
  expect do
26
33
  Configuration.default
@@ -34,9 +41,9 @@ module SecureHeaders
34
41
  config.csp = { default_src: %w('self'), script_src: %w('self')}
35
42
  config.csp_report_only = config.csp
36
43
  end
37
- SecureHeaders.opt_out_of_header(request, ContentSecurityPolicyConfig::CONFIG_KEY)
38
- SecureHeaders.opt_out_of_header(request, ContentSecurityPolicyReportOnlyConfig::CONFIG_KEY)
39
- SecureHeaders.opt_out_of_header(request, XContentTypeOptions::CONFIG_KEY)
44
+ SecureHeaders.opt_out_of_header(request, :csp)
45
+ SecureHeaders.opt_out_of_header(request, :csp_report_only)
46
+ SecureHeaders.opt_out_of_header(request, :x_content_type_options)
40
47
  hash = SecureHeaders.header_hash_for(request)
41
48
  expect(hash["Content-Security-Policy-Report-Only"]).to be_nil
42
49
  expect(hash["Content-Security-Policy"]).to be_nil
@@ -60,6 +67,24 @@ module SecureHeaders
60
67
  expect(hash["X-Frame-Options"]).to be_nil
61
68
  end
62
69
 
70
+ it "Overrides the current default config if default config changes during request" do
71
+ Configuration.default do |config|
72
+ config.x_frame_options = OPT_OUT
73
+ end
74
+
75
+ # Dynamically update the default config for this request
76
+ SecureHeaders.override_x_frame_options(request, "DENY")
77
+
78
+ Configuration.override(:dynamic_override) do |config|
79
+ config.x_content_type_options = "nosniff"
80
+ end
81
+
82
+ SecureHeaders.use_secure_headers_override(request, :dynamic_override)
83
+ hash = SecureHeaders.header_hash_for(request)
84
+ expect(hash["X-Content-Type-Options"]).to eq("nosniff")
85
+ expect(hash["X-Frame-Options"]).to eq("DENY")
86
+ end
87
+
63
88
  it "allows you to opt out entirely" do
64
89
  # configure the disabled-by-default headers to ensure they also do not get set
65
90
  Configuration.default do |config|
@@ -78,9 +103,6 @@ module SecureHeaders
78
103
  end
79
104
  SecureHeaders.opt_out_of_all_protection(request)
80
105
  hash = SecureHeaders.header_hash_for(request)
81
- ALL_HEADER_CLASSES.each do |klass|
82
- expect(hash[klass::CONFIG_KEY]).to be_nil
83
- end
84
106
  expect(hash.count).to eq(0)
85
107
  end
86
108
 
@@ -116,7 +138,7 @@ module SecureHeaders
116
138
  firefox_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:firefox]))
117
139
 
118
140
  # append an unsupported directive
119
- SecureHeaders.override_content_security_policy_directives(firefox_request, {plugin_types: %w(flash)})
141
+ SecureHeaders.override_content_security_policy_directives(firefox_request, {plugin_types: %w(application/pdf)})
120
142
  # append a supported directive
121
143
  SecureHeaders.override_content_security_policy_directives(firefox_request, {script_src: %w('self')})
122
144
 
@@ -265,21 +287,6 @@ module SecureHeaders
265
287
  expect(hash[ContentSecurityPolicyConfig::HEADER_NAME]).to eq("default-src https:; img-src data:; script-src 'self'")
266
288
  end
267
289
 
268
- it "does not append a nonce when the browser does not support it" do
269
- Configuration.default do |config|
270
- config.csp = {
271
- default_src: %w('self'),
272
- script_src: %w(mycdn.com 'unsafe-inline'),
273
- style_src: %w('self')
274
- }
275
- end
276
-
277
- safari_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:safari5]))
278
- SecureHeaders.content_security_policy_script_nonce(safari_request)
279
- hash = SecureHeaders.header_hash_for(safari_request)
280
- expect(hash[ContentSecurityPolicyConfig::HEADER_NAME]).to eq("default-src 'self'; script-src mycdn.com 'unsafe-inline'; style-src 'self'")
281
- end
282
-
283
290
  it "appends a nonce to the script-src when used" do
284
291
  Configuration.default do |config|
285
292
  config.csp = {
@@ -297,21 +304,7 @@ module SecureHeaders
297
304
  SecureHeaders.content_security_policy_script_nonce(chrome_request)
298
305
 
299
306
  hash = SecureHeaders.header_hash_for(chrome_request)
300
- expect(hash["Content-Security-Policy"]).to eq("default-src 'self'; script-src mycdn.com 'nonce-#{nonce}'; style-src 'self'")
301
- end
302
-
303
- it "uses a nonce for safari 10+" do
304
- Configuration.default do |config|
305
- config.csp = {
306
- default_src: %w('self'),
307
- script_src: %w(mycdn.com)
308
- }
309
- end
310
-
311
- safari_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:safari10]))
312
- nonce = SecureHeaders.content_security_policy_script_nonce(safari_request)
313
- hash = SecureHeaders.header_hash_for(safari_request)
314
- expect(hash["Content-Security-Policy"]).to eq("default-src 'self'; script-src mycdn.com 'nonce-#{nonce}'")
307
+ expect(hash["Content-Security-Policy"]).to eq("default-src 'self'; script-src mycdn.com 'nonce-#{nonce}' 'unsafe-inline'; style-src 'self'")
315
308
  end
316
309
 
317
310
  it "does not support the deprecated `report_only: true` format" do
@@ -322,7 +315,7 @@ module SecureHeaders
322
315
  report_only: true
323
316
  }
324
317
  end
325
- }.to raise_error(ArgumentError)
318
+ }.to raise_error(ContentSecurityPolicyConfigError)
326
319
  end
327
320
 
328
321
  it "Raises an error if csp_report_only is used with `report_only: false`" do
@@ -349,6 +342,7 @@ module SecureHeaders
349
342
  end
350
343
 
351
344
  it "sets identical values when the configs are the same" do
345
+ reset_config
352
346
  Configuration.default do |config|
353
347
  config.csp = {
354
348
  default_src: %w('self'),
@@ -366,6 +360,7 @@ module SecureHeaders
366
360
  end
367
361
 
368
362
  it "sets different headers when the configs are different" do
363
+ reset_config
369
364
  Configuration.default do |config|
370
365
  config.csp = {
371
366
  default_src: %w('self'),
@@ -376,10 +371,11 @@ module SecureHeaders
376
371
 
377
372
  hash = SecureHeaders.header_hash_for(request)
378
373
  expect(hash["Content-Security-Policy"]).to eq("default-src 'self'; script-src 'self'")
379
- expect(hash["Content-Security-Policy-Report-Only"]).to eq("default-src 'self'; script-src 'self' foo.com")
374
+ expect(hash["Content-Security-Policy-Report-Only"]).to eq("default-src 'self'; script-src foo.com")
380
375
  end
381
376
 
382
377
  it "allows you to opt-out of enforced CSP" do
378
+ reset_config
383
379
  Configuration.default do |config|
384
380
  config.csp = SecureHeaders::OPT_OUT
385
381
  config.csp_report_only = {
@@ -437,6 +433,7 @@ module SecureHeaders
437
433
 
438
434
  context "when inferring which config to modify" do
439
435
  it "updates the enforced header when configured" do
436
+ reset_config
440
437
  Configuration.default do |config|
441
438
  config.csp = {
442
439
  default_src: %w('self'),
@@ -451,6 +448,7 @@ module SecureHeaders
451
448
  end
452
449
 
453
450
  it "updates the report only header when configured" do
451
+ reset_config
454
452
  Configuration.default do |config|
455
453
  config.csp = OPT_OUT
456
454
  config.csp_report_only = {
@@ -466,6 +464,7 @@ module SecureHeaders
466
464
  end
467
465
 
468
466
  it "updates both headers if both are configured" do
467
+ reset_config
469
468
  Configuration.default do |config|
470
469
  config.csp = {
471
470
  default_src: %w(enforced.com),
data/spec/spec_helper.rb CHANGED
@@ -26,6 +26,7 @@ USER_AGENTS = {
26
26
 
27
27
  def expect_default_values(hash)
28
28
  expect(hash[SecureHeaders::ContentSecurityPolicyConfig::HEADER_NAME]).to eq("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'")
29
+ expect(hash[SecureHeaders::ContentSecurityPolicyReportOnlyConfig::HEADER_NAME]).to be_nil
29
30
  expect(hash[SecureHeaders::XFrameOptions::HEADER_NAME]).to eq(SecureHeaders::XFrameOptions::DEFAULT_VALUE)
30
31
  expect(hash[SecureHeaders::XDownloadOptions::HEADER_NAME]).to eq(SecureHeaders::XDownloadOptions::DEFAULT_VALUE)
31
32
  expect(hash[SecureHeaders::StrictTransportSecurity::HEADER_NAME]).to eq(SecureHeaders::StrictTransportSecurity::DEFAULT_VALUE)
@@ -34,18 +35,21 @@ def expect_default_values(hash)
34
35
  expect(hash[SecureHeaders::XPermittedCrossDomainPolicies::HEADER_NAME]).to eq(SecureHeaders::XPermittedCrossDomainPolicies::DEFAULT_VALUE)
35
36
  expect(hash[SecureHeaders::ReferrerPolicy::HEADER_NAME]).to be_nil
36
37
  expect(hash[SecureHeaders::ExpectCertificateTransparency::HEADER_NAME]).to be_nil
38
+ expect(hash[SecureHeaders::ClearSiteData::HEADER_NAME]).to be_nil
39
+ expect(hash[SecureHeaders::ExpectCertificateTransparency::HEADER_NAME]).to be_nil
40
+ expect(hash[SecureHeaders::PublicKeyPins::HEADER_NAME]).to be_nil
37
41
  end
38
42
 
39
43
  module SecureHeaders
40
44
  class Configuration
41
45
  class << self
42
- def clear_configurations
43
- @configurations = nil
46
+ def clear_default_config
47
+ remove_instance_variable(:@default_config) if defined?(@default_config)
44
48
  end
45
49
  end
46
50
  end
47
51
  end
48
52
 
49
53
  def reset_config
50
- SecureHeaders::Configuration.clear_configurations
54
+ SecureHeaders::Configuration.clear_default_config
51
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secure_headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.5
4
+ version: 6.0.0.alpha01
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Matatall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-12 00:00:00.000000000 Z
11
+ date: 2018-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -69,6 +69,7 @@ files:
69
69
  - docs/upgrading-to-3-0.md
70
70
  - docs/upgrading-to-4-0.md
71
71
  - docs/upgrading-to-5-0.md
72
+ - docs/upgrading-to-6-0.md
72
73
  - lib/secure_headers.rb
73
74
  - lib/secure_headers/configuration.rb
74
75
  - lib/secure_headers/hash_helper.rb
@@ -125,9 +126,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
126
  version: '0'
126
127
  required_rubygems_version: !ruby/object:Gem::Requirement
127
128
  requirements:
128
- - - ">="
129
+ - - ">"
129
130
  - !ruby/object:Gem::Version
130
- version: '0'
131
+ version: 1.3.1
131
132
  requirements: []
132
133
  rubyforge_project:
133
134
  rubygems_version: 2.6.13