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
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,11 @@
1
- require 'rubygems'
2
- require 'rspec'
3
- require 'rack'
4
- require 'pry-nav'
5
-
6
- require 'coveralls'
1
+ # frozen_string_literal: true
2
+ require "rubygems"
3
+ require "rspec"
4
+ require "rack"
5
+ require "coveralls"
7
6
  Coveralls.wear!
8
7
 
9
- require File.join(File.dirname(__FILE__), '..', 'lib', 'secure_headers')
8
+ require File.join(File.dirname(__FILE__), "..", "lib", "secure_headers")
10
9
 
11
10
 
12
11
 
@@ -14,9 +13,9 @@ USER_AGENTS = {
14
13
  edge: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
15
14
  firefox: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1",
16
15
  firefox46: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0",
17
- chrome: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5',
18
- ie: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)',
19
- opera: 'Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00',
16
+ chrome: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5",
17
+ ie: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)",
18
+ opera: "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
20
19
  ios5: "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3",
21
20
  ios6: "Mozilla/5.0 (iPhone; CPU iPhone OS 614 like Mac OS X) AppleWebKit/536.26 (KHTML like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25",
22
21
  safari5: "Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3",
@@ -34,7 +33,6 @@ def expect_default_values(hash)
34
33
  expect(hash[SecureHeaders::XContentTypeOptions::HEADER_NAME]).to eq(SecureHeaders::XContentTypeOptions::DEFAULT_VALUE)
35
34
  expect(hash[SecureHeaders::XPermittedCrossDomainPolicies::HEADER_NAME]).to eq(SecureHeaders::XPermittedCrossDomainPolicies::DEFAULT_VALUE)
36
35
  expect(hash[SecureHeaders::ReferrerPolicy::HEADER_NAME]).to be_nil
37
- expect(hash[SecureHeaders::ExpectCertificateTransparency::HEADER_NAME]).to be_nil
38
36
  end
39
37
 
40
38
  module SecureHeaders
@@ -50,15 +48,3 @@ end
50
48
  def reset_config
51
49
  SecureHeaders::Configuration.clear_configurations
52
50
  end
53
-
54
- def capture_warning
55
- begin
56
- old_stderr = $stderr
57
- $stderr = StringIO.new
58
- yield
59
- result = $stderr.string
60
- ensure
61
- $stderr = old_stderr
62
- end
63
- result
64
- end
@@ -0,0 +1,49 @@
1
+ ### Breaking Changes
2
+
3
+ The most likely change to break your app is the new cookie defaults. This is the first place to check. If you're using the default CSP, your policy will change but your app should not break. This should not break brand new projects using secure_headers either.
4
+
5
+ ## All cookies default to secure/httponly/SameSite=Lax
6
+
7
+ By default, *all* cookies will be marked as `SameSite=lax`,`secure`, and `httponly`. To opt-out, supply `OPT_OUT` as the value for `SecureHeaders.cookies` or the individual configs. Setting these values to `false` will raise an error.
8
+
9
+ ```ruby
10
+ # specific opt outs
11
+ config.cookies = {
12
+ secure: OPT_OUT,
13
+ httponly: OPT_OUT,
14
+ samesite: OPT_OUT,
15
+ }
16
+
17
+ # nuclear option, just make things work again
18
+ config.cookies = OPT_OUT
19
+ ```
20
+
21
+ ## Default Content Security Policy
22
+
23
+ The default CSP has changed to be more universal without sacrificing too much security.
24
+
25
+ * Flash/Java disabled by default
26
+ * `img-src` allows data: images and favicons (among others)
27
+ * `style-src` allows inline CSS by default (most find it impossible/impractical to remove inline content today)
28
+ * `form-action` (not governed by `default-src`, practically treated as `*`) is set to `'self'`
29
+
30
+ Previously, the default CSP was:
31
+
32
+ `Content-Security-Policy: default-src 'self'`
33
+
34
+ The new default policy is:
35
+
36
+ `default-src https:; form-action 'self'; img-src https: data: 'self'; object-src 'none'; script-src https:; style-src 'self' 'unsafe-inline' https:`
37
+
38
+ ## CSP configuration
39
+
40
+ * Setting `report_only: true` in a CSP config will raise an error. Instead, set `csp_report_only`.
41
+ * Setting `frame_src` and `child_src` when values don't match will raise an error. Just use `frame_src`.
42
+
43
+ ## config.secure_cookies removed
44
+
45
+ Use `config.cookies` instead.
46
+
47
+ ## Supported ruby versions
48
+
49
+ We've dropped support for ruby versions <= 2.2. Sorry.
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: 3.9.0
4
+ version: 4.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: 2020-01-21 00:00:00.000000000 Z
11
+ date: 2017-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 0.15.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 0.15.0
41
41
  description: Manages application of security headers with many safe defaults.
42
42
  email:
43
43
  - neil.matatall@gmail.com
@@ -49,6 +49,7 @@ files:
49
49
  - ".github/PULL_REQUEST_TEMPLATE.md"
50
50
  - ".gitignore"
51
51
  - ".rspec"
52
+ - ".rubocop.yml"
52
53
  - ".ruby-gemset"
53
54
  - ".ruby-version"
54
55
  - ".travis.yml"
@@ -73,7 +74,6 @@ files:
73
74
  - lib/secure_headers/headers/content_security_policy.rb
74
75
  - lib/secure_headers/headers/content_security_policy_config.rb
75
76
  - lib/secure_headers/headers/cookie.rb
76
- - lib/secure_headers/headers/expect_certificate_transparency.rb
77
77
  - lib/secure_headers/headers/policy_management.rb
78
78
  - lib/secure_headers/headers/public_key_pins.rb
79
79
  - lib/secure_headers/headers/referrer_policy.rb
@@ -93,7 +93,6 @@ files:
93
93
  - spec/lib/secure_headers/headers/clear_site_data_spec.rb
94
94
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
95
95
  - spec/lib/secure_headers/headers/cookie_spec.rb
96
- - spec/lib/secure_headers/headers/expect_certificate_transparency_spec.rb
97
96
  - spec/lib/secure_headers/headers/policy_management_spec.rb
98
97
  - spec/lib/secure_headers/headers/public_key_pins_spec.rb
99
98
  - spec/lib/secure_headers/headers/referrer_policy_spec.rb
@@ -108,11 +107,17 @@ files:
108
107
  - spec/lib/secure_headers_spec.rb
109
108
  - spec/spec_helper.rb
110
109
  - upgrading-to-3-0.md
110
+ - upgrading-to-4-0.md
111
111
  homepage: https://github.com/twitter/secureheaders
112
112
  licenses:
113
113
  - Apache Public License 2.0
114
114
  metadata: {}
115
- post_install_message:
115
+ post_install_message: |2+
116
+
117
+ **********
118
+ :wave: secure_headers 4.0 introduces a lot of breaking changes (in the name of security!). It's highly likely you will need to update your secure_headers cookie configuration to avoid breaking things. See the upgrade guide for details: https://github.com/twitter/secureheaders/blob/master/upgrading-to-4-0.md
119
+ **********
120
+
116
121
  rdoc_options: []
117
122
  require_paths:
118
123
  - lib
@@ -123,11 +128,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
128
  version: '0'
124
129
  required_rubygems_version: !ruby/object:Gem::Requirement
125
130
  requirements:
126
- - - ">="
131
+ - - ">"
127
132
  - !ruby/object:Gem::Version
128
- version: '0'
133
+ version: 1.3.1
129
134
  requirements: []
130
- rubygems_version: 3.1.2
135
+ rubyforge_project:
136
+ rubygems_version: 2.6.11
131
137
  signing_key:
132
138
  specification_version: 4
133
139
  summary: Add easily configured security headers to responses including content-security-policy,
@@ -137,7 +143,6 @@ test_files:
137
143
  - spec/lib/secure_headers/headers/clear_site_data_spec.rb
138
144
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
139
145
  - spec/lib/secure_headers/headers/cookie_spec.rb
140
- - spec/lib/secure_headers/headers/expect_certificate_transparency_spec.rb
141
146
  - spec/lib/secure_headers/headers/policy_management_spec.rb
142
147
  - spec/lib/secure_headers/headers/public_key_pins_spec.rb
143
148
  - spec/lib/secure_headers/headers/referrer_policy_spec.rb
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
- module SecureHeaders
3
- class ExpectCertificateTransparencyConfigError < StandardError; end
4
-
5
- class ExpectCertificateTransparency
6
- HEADER_NAME = "Expect-CT".freeze
7
- CONFIG_KEY = :expect_certificate_transparency
8
- INVALID_CONFIGURATION_ERROR = "config must be a hash.".freeze
9
- INVALID_ENFORCE_VALUE_ERROR = "enforce must be a boolean".freeze
10
- REQUIRED_MAX_AGE_ERROR = "max-age is a required directive.".freeze
11
- INVALID_MAX_AGE_ERROR = "max-age must be a number.".freeze
12
-
13
- class << self
14
- # Public: Generate a Expect-CT header.
15
- #
16
- # Returns nil if not configured, returns header name and value if
17
- # configured.
18
- def make_header(config)
19
- return if config.nil?
20
-
21
- header = new(config)
22
- [HEADER_NAME, header.value]
23
- end
24
-
25
- def validate_config!(config)
26
- return if config.nil? || config == OPT_OUT
27
- raise ExpectCertificateTransparencyConfigError.new(INVALID_CONFIGURATION_ERROR) unless config.is_a? Hash
28
-
29
- unless [true, false, nil].include?(config[:enforce])
30
- raise ExpectCertificateTransparencyConfigError.new(INVALID_ENFORCE_VALUE_ERROR)
31
- end
32
-
33
- if !config[:max_age]
34
- raise ExpectCertificateTransparencyConfigError.new(REQUIRED_MAX_AGE_ERROR)
35
- elsif config[:max_age].to_s !~ /\A\d+\z/
36
- raise ExpectCertificateTransparencyConfigError.new(INVALID_MAX_AGE_ERROR)
37
- end
38
- end
39
- end
40
-
41
- def initialize(config)
42
- @enforced = config.fetch(:enforce, nil)
43
- @max_age = config.fetch(:max_age, nil)
44
- @report_uri = config.fetch(:report_uri, nil)
45
- end
46
-
47
- def value
48
- header_value = [
49
- enforced_directive,
50
- max_age_directive,
51
- report_uri_directive
52
- ].compact.join(", ").strip
53
- end
54
-
55
- def enforced_directive
56
- # Unfortunately `if @enforced` isn't enough here in case someone
57
- # passes in a random string so let's be specific with it to prevent
58
- # accidental enforcement.
59
- "enforce" if @enforced == true
60
- end
61
-
62
- def max_age_directive
63
- "max-age=#{@max_age}" if @max_age
64
- end
65
-
66
- def report_uri_directive
67
- "report-uri=\"#{@report_uri}\"" if @report_uri
68
- end
69
- end
70
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
-
4
- module SecureHeaders
5
- describe ExpectCertificateTransparency do
6
- specify { expect(ExpectCertificateTransparency.new(max_age: 1234, enforce: true).value).to eq("enforce, max-age=1234") }
7
- specify { expect(ExpectCertificateTransparency.new(max_age: 1234, enforce: false).value).to eq("max-age=1234") }
8
- specify { expect(ExpectCertificateTransparency.new(max_age: 1234, enforce: "yolocopter").value).to eq("max-age=1234") }
9
- specify { expect(ExpectCertificateTransparency.new(max_age: 1234, report_uri: "https://report-uri.io/expect-ct").value).to eq("max-age=1234, report-uri=\"https://report-uri.io/expect-ct\"") }
10
- specify do
11
- config = { enforce: true, max_age: 1234, report_uri: "https://report-uri.io/expect-ct" }
12
- header_value = "enforce, max-age=1234, report-uri=\"https://report-uri.io/expect-ct\""
13
- expect(ExpectCertificateTransparency.new(config).value).to eq(header_value)
14
- end
15
-
16
- context "with an invalid configuration" do
17
- it "raises an exception when configuration isn't a hash" do
18
- expect do
19
- ExpectCertificateTransparency.validate_config!(%w(a))
20
- end.to raise_error(ExpectCertificateTransparencyConfigError)
21
- end
22
-
23
- it "raises an exception when max-age is not provided" do
24
- expect do
25
- ExpectCertificateTransparency.validate_config!(foo: "bar")
26
- end.to raise_error(ExpectCertificateTransparencyConfigError)
27
- end
28
-
29
- it "raises an exception with an invalid max-age" do
30
- expect do
31
- ExpectCertificateTransparency.validate_config!(max_age: "abc123")
32
- end.to raise_error(ExpectCertificateTransparencyConfigError)
33
- end
34
-
35
- it "raises an exception with an invalid enforce value" do
36
- expect do
37
- ExpectCertificateTransparency.validate_config!(enforce: "brokenstring")
38
- end.to raise_error(ExpectCertificateTransparencyConfigError)
39
- end
40
- end
41
- end
42
- end