secure_headers 3.9.0 → 4.0.0.alpha01

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of secure_headers might be problematic. Click here for more details.

Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +3 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +8 -6
  6. data/CHANGELOG.md +2 -34
  7. data/CONTRIBUTING.md +1 -1
  8. data/Gemfile +7 -4
  9. data/Guardfile +1 -0
  10. data/README.md +4 -25
  11. data/Rakefile +22 -18
  12. data/docs/cookies.md +18 -5
  13. data/lib/secure_headers.rb +1 -2
  14. data/lib/secure_headers/configuration.rb +6 -16
  15. data/lib/secure_headers/hash_helper.rb +2 -1
  16. data/lib/secure_headers/headers/clear_site_data.rb +2 -1
  17. data/lib/secure_headers/headers/content_security_policy.rb +14 -60
  18. data/lib/secure_headers/headers/content_security_policy_config.rb +1 -1
  19. data/lib/secure_headers/headers/cookie.rb +22 -10
  20. data/lib/secure_headers/headers/policy_management.rb +57 -98
  21. data/lib/secure_headers/headers/public_key_pins.rb +4 -3
  22. data/lib/secure_headers/headers/referrer_policy.rb +1 -0
  23. data/lib/secure_headers/headers/strict_transport_security.rb +2 -1
  24. data/lib/secure_headers/headers/x_content_type_options.rb +1 -0
  25. data/lib/secure_headers/headers/x_download_options.rb +2 -1
  26. data/lib/secure_headers/headers/x_frame_options.rb +1 -0
  27. data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +2 -1
  28. data/lib/secure_headers/headers/x_xss_protection.rb +2 -1
  29. data/lib/secure_headers/middleware.rb +10 -9
  30. data/lib/secure_headers/railtie.rb +7 -6
  31. data/lib/secure_headers/utils/cookies_config.rb +17 -18
  32. data/lib/secure_headers/view_helper.rb +2 -1
  33. data/lib/tasks/tasks.rake +2 -1
  34. data/secure_headers.gemspec +13 -3
  35. data/spec/lib/secure_headers/configuration_spec.rb +9 -8
  36. data/spec/lib/secure_headers/headers/clear_site_data_spec.rb +2 -1
  37. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +17 -53
  38. data/spec/lib/secure_headers/headers/cookie_spec.rb +58 -37
  39. data/spec/lib/secure_headers/headers/policy_management_spec.rb +20 -41
  40. data/spec/lib/secure_headers/headers/public_key_pins_spec.rb +7 -6
  41. data/spec/lib/secure_headers/headers/referrer_policy_spec.rb +4 -3
  42. data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +5 -4
  43. data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +2 -1
  44. data/spec/lib/secure_headers/headers/x_download_options_spec.rb +3 -2
  45. data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +2 -1
  46. data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +4 -3
  47. data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +4 -3
  48. data/spec/lib/secure_headers/middleware_spec.rb +18 -21
  49. data/spec/lib/secure_headers/view_helpers_spec.rb +5 -4
  50. data/spec/lib/secure_headers_spec.rb +92 -120
  51. data/spec/spec_helper.rb +9 -23
  52. data/upgrading-to-4-0.md +49 -0
  53. metadata +16 -11
  54. data/lib/secure_headers/headers/expect_certificate_transparency.rb +0 -70
  55. data/spec/lib/secure_headers/headers/expect_certificate_transparency_spec.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 6e2f294d6c2130a1f629bf3dba2a88da71fa2b80a015cb7dc96bcbbcb88d1d59
4
- data.tar.gz: 767021dbec7d023bbcb629b3315ad10ff989e2c6ae7ceff9ffc5614b05fa3ba5
2
+ SHA1:
3
+ metadata.gz: 1cfa800eacf250583e379d13a9149d585bc2f48d
4
+ data.tar.gz: 3de8c81b1308ec9d1d53f822cff8eeb7e20b5af0
5
5
  SHA512:
6
- metadata.gz: 86d16e60409fca6b72e16321100a6afc3cc1fded1fb79c004778c8cdae2872ed4751205e90274f4b2c0517a70763c896692d9bd547f3b5b9144b8479b93268d5
7
- data.tar.gz: a2462e058ad88292d40e5a7e4e23e0a5ba431a8a114616f1e1d77bd5218e99ed0b68f4e7b0cf9e3480e10ca2e34e97d60e3b7b1d77db8b71da71c031f4cdaa52
6
+ metadata.gz: 4c25ae5372ac00f74b0cae3b7de0a767a15b45f275bed64994c2cd7d078a2f0b52bdce562d14280984ad494fd008445d5d5448a3ac94694cd1f9778da3deeacc
7
+ data.tar.gz: 6fab2c382ed56f9a63dd118a34b617fb82b4ee4e9ef55f37d78e134ec9068c9ee1022ba0a94991d0b7b82ea756d78132d3c0dfc909e66d4068acde4f6d2673ff
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --order rand
2
2
  --warnings
3
+ --format progress
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_gem:
2
+ rubocop-github:
3
+ - config/default.yml
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.3
1
+ 2.4.1
data/.travis.yml CHANGED
@@ -2,15 +2,17 @@ language: ruby
2
2
 
3
3
  rvm:
4
4
  - ruby-head
5
- - 2.4.0
6
- - 2.3.3
5
+ - 2.4.1
6
+ - 2.3.4
7
7
  - 2.2
8
- - 2.1
9
- - 2.0.0
10
- - 1.9.3
11
- - jruby-19mode
12
8
  - jruby-head
13
9
 
10
+ env:
11
+ - SUITE=rspec spec
12
+ - SUITE=rubocop
13
+
14
+ script: bundle exec $SUITE
15
+
14
16
  matrix:
15
17
  allow_failures:
16
18
  - rvm: jruby-head
data/CHANGELOG.md CHANGED
@@ -1,38 +1,6 @@
1
- ## 3.9.0
1
+ ## 4.x
2
2
 
3
- Fixes newline injection issue
4
-
5
- ## 3.8.0
6
-
7
- Fixes semicolon injection issue reported by @mvgijssel see https://github.com/twitter/secure_headers/issues/418
8
-
9
- ## 3.7.4
10
-
11
- Backport SameSite=None functionality into 3.x line
12
-
13
- ## 3.7.3
14
-
15
- - Updates `Expect-CT` header to use a comma separator between directives, as specified in the most current spec.
16
-
17
- ## 3.7.2
18
-
19
- - Adds support for `worker-src` CSP directive to 3.x line (https://github.com/twitter/secureheaders/pull/364)
20
-
21
- ## 3.7.1
22
-
23
- Fix support for the sandbox attribute of CSP. `true` and `[]` represent the maximally restricted policy (`sandbox;`) and validate other values.
24
-
25
- ## 3.7.0
26
-
27
- Adds support for the `Expect-CT` header (@jacobbednarz: https://github.com/twitter/secureheaders/pull/322)
28
-
29
- ## 3.6.7
30
-
31
- Actually set manifest-src when configured. https://github.com/twitter/secureheaders/pull/339 Thanks @carlosantoniodasilva!
32
-
33
- ## 3.6.6
34
-
35
- wat?
3
+ - See the [upgrading to 4.0](upgrading-to-4.0.md) guide. Lots of breaking changes.
36
4
 
37
5
  ## 3.6.5
38
6
 
data/CONTRIBUTING.md CHANGED
@@ -30,7 +30,7 @@ Here are a few things you can do that will increase the likelihood of your pull
30
30
  0. Ensure CI is green
31
31
  0. Pull the latest code
32
32
  0. Increment the version
33
- 0. Run `gem build darrrr.gemspec`
33
+ 0. Run `gem build secure_headers.gemspec`
34
34
  0. Bump the Gemfile and Gemfile.lock versions for an app which relies on this gem
35
35
  0. Test behavior locally, branch deploy, whatever needs to happen
36
36
  0. Run `bundle exec rake release`
data/Gemfile CHANGED
@@ -1,19 +1,22 @@
1
+ # frozen_string_literal: true
1
2
  source "https://rubygems.org"
2
3
 
3
4
  gemspec
4
5
 
5
6
  group :test do
6
- gem "tins", "~> 1.6.0" # 1.7 requires ruby 2.0
7
- gem "pry-nav"
7
+ gem "coveralls"
8
8
  gem "json", "~> 1"
9
+ gem "pry-nav"
9
10
  gem "rack", "~> 1"
10
11
  gem "rspec"
11
- gem "coveralls"
12
+ gem "rubocop", "~> 0.47.0"
13
+ gem "rubocop-github"
12
14
  gem "term-ansicolor", "< 1.4"
15
+ gem "tins", "~> 1.6.0" # 1.7 requires ruby 2.0
13
16
  end
14
17
 
15
18
  group :guard do
16
- gem "guard-rspec", platforms: [:ruby_19, :ruby_20, :ruby_21, :ruby_22]
17
19
  gem "growl"
20
+ gem "guard-rspec", platforms: [:ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24]
18
21
  gem "rb-fsevent"
19
22
  end
data/Guardfile CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  guard :rspec, cmd: "bundle exec rspec", all_on_start: true, all_after_pass: true do
2
3
  require "guard/rspec/dsl"
3
4
  dsl = Guard::RSpec::Dsl.new(self)
data/README.md CHANGED
@@ -1,9 +1,10 @@
1
1
  # Secure Headers [![Build Status](https://travis-ci.org/twitter/secureheaders.svg?branch=master)](http://travis-ci.org/twitter/secureheaders) [![Code Climate](https://codeclimate.com/github/twitter/secureheaders.svg)](https://codeclimate.com/github/twitter/secureheaders) [![Coverage Status](https://coveralls.io/repos/twitter/secureheaders/badge.svg)](https://coveralls.io/r/twitter/secureheaders)
2
2
 
3
+ **master represents the unreleased 4.x line**. See the [upgrading to 4.x doc](upgrading-to-4-0.md) for instructions on how to upgrade. Bug fixes should go in the 3.x branch for now.
3
4
 
4
- **The 3.x branch was recently merged**. See the [upgrading to 3.x doc](upgrading-to-3-0.md) for instructions on how to upgrade including the differences and benefits of using the 3.x branch.
5
+ **The [3.x](https://github.com/twitter/secureheaders/tree/2.x) branch is moving into maintenance mode**. See the [upgrading to 3.x doc](upgrading-to-3-0.md) for instructions on how to upgrade including the differences and benefits of using the 3.x branch.
5
6
 
6
- **The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be maintained**. The documentation below only applies to the 3.x branch. See the 2.x [README](https://github.com/twitter/secureheaders/blob/2.x/README.md) for the old way of doing things.
7
+ **The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be not be maintained once 4.x is released**. The documentation below only applies to the 3.x branch. See the 2.x [README](https://github.com/twitter/secureheaders/blob/2.x/README.md) for the old way of doing things.
7
8
 
8
9
  The gem will automatically apply several headers that are related to security. This includes:
9
10
  - Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack. [CSP 2 Specification](http://www.w3.org/TR/CSP2/)
@@ -18,7 +19,6 @@ The gem will automatically apply several headers that are related to security.
18
19
  - X-Permitted-Cross-Domain-Policies - [Restrict Adobe Flash Player's access to data](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html)
19
20
  - Referrer-Policy - [Referrer Policy draft](https://w3c.github.io/webappsec-referrer-policy/)
20
21
  - Public Key Pinning - Pin certificate fingerprints in the browser to prevent man-in-the-middle attacks due to compromised Certificate Authorities. [Public Key Pinning Specification](https://tools.ietf.org/html/rfc7469)
21
- - Expect-CT - Only use certificates that are present in the certificate transparency logs. [Expect-CT draft specification](https://datatracker.ietf.org/doc/draft-stark-expect-ct/).
22
22
  - Clear-Site-Data - Clearing browser data for origin. [Clear-Site-Data specification](https://w3c.github.io/webappsec-clear-site-data/).
23
23
 
24
24
  It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes (when configured to do so).
@@ -77,14 +77,8 @@ SecureHeaders::Configuration.default do |config|
77
77
  "storage",
78
78
  "executionContexts"
79
79
  ]
80
- config.expect_certificate_transparency = {
81
- enforce: false,
82
- max_age: 1.day.to_i,
83
- report_uri: "https://report-uri.io/example-ct"
84
- }
85
80
  config.csp = {
86
- # "meta" values. these will shaped the header, but the values are not included in the header.
87
- # report_only: true, # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
81
+ # "meta" values. these will shape the header, but the values are not included in the header.
88
82
  preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
89
83
 
90
84
  # directive values: these values will directly translate into source directives
@@ -103,7 +97,6 @@ SecureHeaders::Configuration.default do |config|
103
97
  plugin_types: %w(application/x-shockwave-flash),
104
98
  script_src: %w('self'),
105
99
  style_src: %w('unsafe-inline'),
106
- worker_src: %w('self'),
107
100
  upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
108
101
  report_uri: %w(https://report-uri.io/example-csp)
109
102
  }
@@ -139,20 +132,6 @@ X-Permitted-Cross-Domain-Policies: none
139
132
  X-Xss-Protection: 1; mode=block
140
133
  ```
141
134
 
142
- ### Default CSP
143
-
144
- By default, the above CSP will be applied to all requests. If you **only** want to set a Report-Only header, opt-out of the default enforced header for clarity. The configuration will assume that if you only supply `csp_report_only` that you intended to opt-out of `csp` but that's for the sake of backwards compatibility and it will be removed in the future.
145
-
146
- ```ruby
147
- Configuration.default do |config|
148
- config.csp = SecureHeaders::OPT_OUT # If this line is omitted, we will assume you meant to opt out.
149
- config.csp_report_only = {
150
- default_src: %w('self')
151
- }
152
- end
153
- ```
154
-
155
-
156
135
  ## Similar libraries
157
136
 
158
137
  * Rack [rack-secure_headers](https://github.com/frodsan/rack-secure_headers)
data/Rakefile CHANGED
@@ -1,28 +1,32 @@
1
1
  #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
4
- require 'net/http'
5
- require 'net/https'
2
+ # frozen_string_literal: true
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "net/http"
6
+ require "net/https"
6
7
 
7
- desc "Run RSpec"
8
- RSpec::Core::RakeTask.new do |t|
9
- t.verbose = false
10
- t.rspec_opts = "--format progress"
11
- end
12
-
13
- task default: :spec
8
+ RSpec::Core::RakeTask.new
14
9
 
15
10
  begin
16
- require 'rdoc/task'
11
+ require "rdoc/task"
17
12
  rescue LoadError
18
- require 'rdoc/rdoc'
19
- require 'rake/rdoctask'
13
+ require "rdoc/rdoc"
14
+ require "rake/rdoctask"
20
15
  RDoc::Task = Rake::RDocTask
21
16
  end
22
17
 
18
+ begin
19
+ require "rubocop/rake_task"
20
+ RuboCop::RakeTask.new
21
+ rescue LoadError
22
+ task(:rubocop) { $stderr.puts "RuboCop is disabled" }
23
+ end
24
+
23
25
  RDoc::Task.new(:rdoc) do |rdoc|
24
- rdoc.rdoc_dir = 'rdoc'
25
- rdoc.title = 'SecureHeaders'
26
- rdoc.options << '--line-numbers'
27
- rdoc.rdoc_files.include('lib/**/*.rb')
26
+ rdoc.rdoc_dir = "rdoc"
27
+ rdoc.title = "SecureHeaders"
28
+ rdoc.options << "--line-numbers"
29
+ rdoc.rdoc_files.include("lib/**/*.rb")
28
30
  end
31
+
32
+ task default: [:spec, :rubocop]
data/docs/cookies.md CHANGED
@@ -4,14 +4,28 @@ SecureHeaders supports `Secure`, `HttpOnly` and [`SameSite`](https://tools.ietf.
4
4
 
5
5
  __Note__: Regardless of the configuration specified, Secure cookies are only enabled for HTTPS requests.
6
6
 
7
+ #### Defaults
8
+
9
+ By default, all cookies will get both `Secure`, `HttpOnly`, and `SameSite=Lax`.
10
+
11
+ ```ruby
12
+ config.cookies = {
13
+ secure: true, # defaults to true but will be a no op on non-HTTPS requests
14
+ httponly: true, # defaults to true
15
+ samesite: { # defaults to set `SameSite=Lax`
16
+ lax: true
17
+ }
18
+ }
19
+ ```
20
+
7
21
  #### Boolean-based configuration
8
22
 
9
- Boolean-based configuration is intended to globally enable or disable a specific cookie attribute.
23
+ Boolean-based configuration is intended to globally enable or disable a specific cookie attribute. *Note: As of 4.0, you must use OPT_OUT rather than false to opt out of the defaults.*
10
24
 
11
25
  ```ruby
12
26
  config.cookies = {
13
27
  secure: true, # mark all cookies as Secure
14
- httponly: false, # do not mark any cookies as HttpOnly
28
+ httponly: OPT_OUT, # do not mark any cookies as HttpOnly
15
29
  }
16
30
  ```
17
31
 
@@ -38,14 +52,13 @@ config.cookies = {
38
52
  }
39
53
  ```
40
54
 
41
- `Strict`, `Lax`, and `None` enforcement modes can also be specified using a Hash.
55
+ `Strict` and `Lax` enforcement modes can also be specified using a Hash.
42
56
 
43
57
  ```ruby
44
58
  config.cookies = {
45
59
  samesite: {
46
60
  strict: { only: ['_rails_session'] },
47
- lax: { only: ['_guest'] },
48
- none: { only: ['_tracking'] },
61
+ lax: { only: ['_guest'] }
49
62
  }
50
63
  }
51
64
  ```
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "secure_headers/configuration"
2
3
  require "secure_headers/hash_helper"
3
4
  require "secure_headers/headers/cookie"
@@ -11,7 +12,6 @@ require "secure_headers/headers/x_download_options"
11
12
  require "secure_headers/headers/x_permitted_cross_domain_policies"
12
13
  require "secure_headers/headers/referrer_policy"
13
14
  require "secure_headers/headers/clear_site_data"
14
- require "secure_headers/headers/expect_certificate_transparency"
15
15
  require "secure_headers/middleware"
16
16
  require "secure_headers/railtie"
17
17
  require "secure_headers/view_helper"
@@ -52,7 +52,6 @@ module SecureHeaders
52
52
  CSP = ContentSecurityPolicy
53
53
 
54
54
  ALL_HEADER_CLASSES = [
55
- ExpectCertificateTransparency,
56
55
  ClearSiteData,
57
56
  ContentSecurityPolicyConfig,
58
57
  ContentSecurityPolicyReportOnlyConfig,
@@ -1,4 +1,5 @@
1
- require 'yaml'
1
+ # frozen_string_literal: true
2
+ require "yaml"
2
3
 
3
4
  module SecureHeaders
4
5
  class Configuration
@@ -116,7 +117,7 @@ module SecureHeaders
116
117
 
117
118
  attr_writer :hsts, :x_frame_options, :x_content_type_options,
118
119
  :x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies,
119
- :referrer_policy, :clear_site_data, :expect_certificate_transparency
120
+ :referrer_policy, :clear_site_data
120
121
 
121
122
  attr_reader :cached_headers, :csp, :cookies, :csp_report_only, :hpkp, :hpkp_report_host
122
123
 
@@ -143,7 +144,6 @@ module SecureHeaders
143
144
  @x_frame_options = nil
144
145
  @x_permitted_cross_domain_policies = nil
145
146
  @x_xss_protection = nil
146
- @expect_certificate_transparency = nil
147
147
 
148
148
  self.hpkp = OPT_OUT
149
149
  self.referrer_policy = OPT_OUT
@@ -169,7 +169,6 @@ module SecureHeaders
169
169
  copy.x_download_options = @x_download_options
170
170
  copy.x_permitted_cross_domain_policies = @x_permitted_cross_domain_policies
171
171
  copy.clear_site_data = @clear_site_data
172
- copy.expect_certificate_transparency = @expect_certificate_transparency
173
172
  copy.referrer_policy = @referrer_policy
174
173
  copy.hpkp = @hpkp
175
174
  copy.hpkp_report_host = @hpkp_report_host
@@ -202,14 +201,12 @@ module SecureHeaders
202
201
  XDownloadOptions.validate_config!(@x_download_options)
203
202
  XPermittedCrossDomainPolicies.validate_config!(@x_permitted_cross_domain_policies)
204
203
  ClearSiteData.validate_config!(@clear_site_data)
205
- ExpectCertificateTransparency.validate_config!(@expect_certificate_transparency)
206
204
  PublicKeyPins.validate_config!(@hpkp)
207
205
  Cookie.validate_config!(@cookies)
208
206
  end
209
207
 
210
208
  def secure_cookies=(secure_cookies)
211
- Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] `#secure_cookies=` is deprecated. Please use `#cookies=` to configure secure cookies instead."
212
- @cookies = (@cookies || {}).merge(secure: secure_cookies)
209
+ raise ArgumentError, "#{Kernel.caller.first}: `#secure_cookies=` is no longer supported. Please use `#cookies=` to configure secure cookies instead."
213
210
  end
214
211
 
215
212
  def csp=(new_csp)
@@ -217,10 +214,8 @@ module SecureHeaders
217
214
  @csp = new_csp.dup
218
215
  else
219
216
  if new_csp[:report_only]
220
- # Deprecated configuration implies that CSPRO should be set, CSP should not - so opt out
221
- Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] `#csp=` was supplied a config with report_only: true. Use #csp_report_only="
222
- @csp = OPT_OUT
223
- self.csp_report_only = new_csp
217
+ # invalid configuration implies that CSPRO should be set, CSP should not - so opt out
218
+ raise ArgumentError, "#{Kernel.caller.first}: `#csp=` was supplied a config with report_only: true. Use #csp_report_only="
224
219
  else
225
220
  @csp = ContentSecurityPolicyConfig.new(new_csp)
226
221
  end
@@ -247,11 +242,6 @@ module SecureHeaders
247
242
  end
248
243
  end
249
244
  end
250
-
251
- if !@csp_report_only.opt_out? && @csp.to_h == ContentSecurityPolicyConfig::DEFAULT
252
- Kernel.warn "#{Kernel.caller.first}: [DEPRECATION] `#csp_report_only=` was configured before `#csp=`. It is assumed you intended to opt out of `#csp=` so be sure to add `config.csp = SecureHeaders::OPT_OUT` to your config. Ensure that #csp_report_only is configured after #csp="
253
- @csp = OPT_OUT
254
- end
255
245
  end
256
246
 
257
247
  protected
@@ -1,4 +1,5 @@
1
- require 'base64'
1
+ # frozen_string_literal: true
2
+ require "base64"
2
3
 
3
4
  module SecureHeaders
4
5
  module HashHelper
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module SecureHeaders
2
3
  class ClearSiteDataConfigError < StandardError; end
3
4
  class ClearSiteData
@@ -16,7 +17,7 @@ module SecureHeaders
16
17
  # Public: make an Clear-Site-Data header name, value pair
17
18
  #
18
19
  # Returns nil if not configured, returns header name and value if configured.
19
- def make_header(config=nil)
20
+ def make_header(config = nil)
20
21
  case config
21
22
  when nil, OPT_OUT, []
22
23
  # noop
@@ -1,6 +1,7 @@
1
- require_relative 'policy_management'
2
- require_relative 'content_security_policy_config'
3
- require 'useragent'
1
+ # frozen_string_literal: true
2
+ require_relative "policy_management"
3
+ require_relative "content_security_policy_config"
4
+ require "useragent"
4
5
 
5
6
  module SecureHeaders
6
7
  class ContentSecurityPolicy
@@ -54,18 +55,12 @@ module SecureHeaders
54
55
 
55
56
  private
56
57
 
57
- # frame-src is deprecated, child-src is being implemented. They are
58
- # very similar and in most cases, the same value can be used for both.
59
58
  def normalize_child_frame_src
60
59
  if @config.frame_src && @config.child_src && @config.frame_src != @config.child_src
61
- Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers.")
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."
62
61
  end
63
62
 
64
- if supported_directives.include?(:child_src)
65
- @config.child_src || @config.frame_src
66
- else
67
- @config.frame_src || @config.child_src
68
- end
63
+ @config.frame_src || @config.child_src
69
64
  end
70
65
 
71
66
  # Private: converts the config object into a string representing a policy.
@@ -80,55 +75,20 @@ module SecureHeaders
80
75
  case DIRECTIVE_VALUE_TYPES[directive_name]
81
76
  when :boolean
82
77
  symbol_to_hyphen_case(directive_name) if @config.directive_value(directive_name)
83
- when :sandbox_list
84
- build_sandbox_list_directive(directive_name)
85
- when :media_type_list
86
- build_media_type_list_directive(directive_name)
87
- when :source_list
88
- build_source_list_directive(directive_name)
78
+ when :string
79
+ [symbol_to_hyphen_case(directive_name), @config.directive_value(directive_name)].join(" ")
80
+ else
81
+ build_directive(directive_name)
89
82
  end
90
83
  end.compact.join("; ")
91
84
  end
92
85
 
93
- def build_sandbox_list_directive(directive)
94
- return unless sandbox_list = @config.directive_value(directive)
95
- max_strict_policy = case sandbox_list
96
- when Array
97
- sandbox_list.empty?
98
- when true
99
- true
100
- else
101
- false
102
- end
103
-
104
- # A maximally strict sandbox policy is just the `sandbox` directive,
105
- # whith no configuraiton values.
106
- if max_strict_policy
107
- symbol_to_hyphen_case(directive)
108
- elsif sandbox_list && sandbox_list.any?
109
- [
110
- symbol_to_hyphen_case(directive),
111
- sandbox_list.uniq
112
- ].join(" ")
113
- end
114
- end
115
-
116
- def build_media_type_list_directive(directive)
117
- return unless media_type_list = @config.directive_value(directive)
118
- if media_type_list && media_type_list.any?
119
- [
120
- symbol_to_hyphen_case(directive),
121
- media_type_list.uniq
122
- ].join(" ")
123
- end
124
- end
125
-
126
86
  # Private: builds a string that represents one directive in a minified form.
127
87
  #
128
88
  # directive_name - a symbol representing the various ALL_DIRECTIVES
129
89
  #
130
90
  # Returns a string representing a directive.
131
- def build_source_list_directive(directive)
91
+ def build_directive(directive)
132
92
  source_list = case directive
133
93
  when :child_src
134
94
  if supported_directives.include?(:child_src)
@@ -142,14 +102,8 @@ module SecureHeaders
142
102
  @config.directive_value(directive)
143
103
  end
144
104
  return unless source_list && source_list.any?
145
- normalized_source_list = minify_source_list(directive, source_list).join(" ")
146
-
147
- if normalized_source_list =~ /(\n|;)/
148
- Kernel.warn("#{directive} contains a #{$1} in #{normalized_source_list.inspect} which will raise an error in future versions. It has been replaced with a blank space.")
149
- end
150
- escaped_source_list = normalized_source_list.gsub(/[\n;]/, " ")
151
-
152
- [symbol_to_hyphen_case(directive), escaped_source_list].join(" ").strip
105
+ normalized_source_list = minify_source_list(directive, source_list)
106
+ [symbol_to_hyphen_case(directive), normalized_source_list].join(" ")
153
107
  end
154
108
 
155
109
  # If a directive contains *, all other values are omitted.
@@ -270,7 +224,7 @@ module SecureHeaders
270
224
  end
271
225
 
272
226
  def symbol_to_hyphen_case(sym)
273
- sym.to_s.tr('_', '-')
227
+ sym.to_s.tr("_", "-")
274
228
  end
275
229
  end
276
230
  end