secure_headers 3.6.7 → 3.7.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.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ba9d50d38ff5d5eb3770fd8e2d445ac0c8bf934
4
- data.tar.gz: 0d0a0bd64c859ce0421effd4b1648de3df8acfa1
3
+ metadata.gz: 591de0f41bc64b3520fbb2fdab9fc94b490d1604
4
+ data.tar.gz: f836c5e63e4d054ff2ce3f1ec597bbd9cf67ed4b
5
5
  SHA512:
6
- metadata.gz: d0c708c8b93bf64c601a0fe7c358a9d2270016a80931d786774e8180ca50b7c61207e4f9759fb085fde7703099a1be96c4b5210b642d17a0c13000a4cdc8c51f
7
- data.tar.gz: 00fe77abc4a759ada4b509b899c48f0b0ee62d86b151b5c6a41f6bbde390c4dccc8ed1a33e02ed67a45fa8e2d61da0ebeeefa1c2a59566e587b583f53df98805
6
+ metadata.gz: 5317d425d7c65dfc73b32703aae7e16e3a566b620b42e3233cd6dc7403a1a9842bb7dc00ffc5c13a86240c5a8abee3ae07fed0c73d4b06a06bcc11db39a79a20
7
+ data.tar.gz: 154573bfb9112b4b1510abbde3f5eb1e85b709f7839ff4a6a547223e67e698ff014bb578f02b0e8775ee723016f5903e8cda38cb9846b24cafe3dc8e414bb007
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 3.7.0
2
+
3
+ Adds support for the `Expect-CT` header (@jacobbednarz: https://github.com/twitter/secureheaders/pull/322)
4
+
1
5
  ## 3.6.7
2
6
 
3
7
  Actually set manifest-src when configured. https://github.com/twitter/secureheaders/pull/339 Thanks @carlosantoniodasilva!
data/README.md CHANGED
@@ -18,6 +18,7 @@ The gem will automatically apply several headers that are related to security.
18
18
  - 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
19
  - Referrer-Policy - [Referrer Policy draft](https://w3c.github.io/webappsec-referrer-policy/)
20
20
  - 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/).
21
22
  - Clear-Site-Data - Clearing browser data for origin. [Clear-Site-Data specification](https://w3c.github.io/webappsec-clear-site-data/).
22
23
 
23
24
  It can also mark all http cookies with the Secure, HttpOnly and SameSite attributes (when configured to do so).
@@ -76,6 +77,11 @@ SecureHeaders::Configuration.default do |config|
76
77
  "storage",
77
78
  "executionContexts"
78
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
+ }
79
85
  config.csp = {
80
86
  # "meta" values. these will shaped the header, but the values are not included in the header.
81
87
  # report_only: true, # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
@@ -116,7 +116,7 @@ module SecureHeaders
116
116
 
117
117
  attr_writer :hsts, :x_frame_options, :x_content_type_options,
118
118
  :x_xss_protection, :x_download_options, :x_permitted_cross_domain_policies,
119
- :referrer_policy, :clear_site_data
119
+ :referrer_policy, :clear_site_data, :expect_certificate_transparency
120
120
 
121
121
  attr_reader :cached_headers, :csp, :cookies, :csp_report_only, :hpkp, :hpkp_report_host
122
122
 
@@ -143,6 +143,7 @@ module SecureHeaders
143
143
  @x_frame_options = nil
144
144
  @x_permitted_cross_domain_policies = nil
145
145
  @x_xss_protection = nil
146
+ @expect_certificate_transparency = nil
146
147
 
147
148
  self.hpkp = OPT_OUT
148
149
  self.referrer_policy = OPT_OUT
@@ -168,6 +169,7 @@ module SecureHeaders
168
169
  copy.x_download_options = @x_download_options
169
170
  copy.x_permitted_cross_domain_policies = @x_permitted_cross_domain_policies
170
171
  copy.clear_site_data = @clear_site_data
172
+ copy.expect_certificate_transparency = @expect_certificate_transparency
171
173
  copy.referrer_policy = @referrer_policy
172
174
  copy.hpkp = @hpkp
173
175
  copy.hpkp_report_host = @hpkp_report_host
@@ -200,6 +202,7 @@ module SecureHeaders
200
202
  XDownloadOptions.validate_config!(@x_download_options)
201
203
  XPermittedCrossDomainPolicies.validate_config!(@x_permitted_cross_domain_policies)
202
204
  ClearSiteData.validate_config!(@clear_site_data)
205
+ ExpectCertificateTransparency.validate_config!(@expect_certificate_transparency)
203
206
  PublicKeyPins.validate_config!(@hpkp)
204
207
  Cookie.validate_config!(@cookies)
205
208
  end
@@ -0,0 +1,70 @@
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
@@ -11,6 +11,7 @@ require "secure_headers/headers/x_download_options"
11
11
  require "secure_headers/headers/x_permitted_cross_domain_policies"
12
12
  require "secure_headers/headers/referrer_policy"
13
13
  require "secure_headers/headers/clear_site_data"
14
+ require "secure_headers/headers/expect_certificate_transparency"
14
15
  require "secure_headers/middleware"
15
16
  require "secure_headers/railtie"
16
17
  require "secure_headers/view_helper"
@@ -51,6 +52,7 @@ module SecureHeaders
51
52
  CSP = ContentSecurityPolicy
52
53
 
53
54
  ALL_HEADER_CLASSES = [
55
+ ExpectCertificateTransparency,
54
56
  ClearSiteData,
55
57
  ContentSecurityPolicyConfig,
56
58
  ContentSecurityPolicyReportOnlyConfig,
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = "secure_headers"
4
- gem.version = "3.6.7"
4
+ gem.version = "3.7.0"
5
5
  gem.authors = ["Neil Matatall"]
6
6
  gem.email = ["neil.matatall@gmail.com"]
7
7
  gem.description = 'Manages application of security headers with many safe defaults.'
@@ -0,0 +1,42 @@
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
data/spec/spec_helper.rb CHANGED
@@ -34,6 +34,7 @@ def expect_default_values(hash)
34
34
  expect(hash[SecureHeaders::XContentTypeOptions::HEADER_NAME]).to eq(SecureHeaders::XContentTypeOptions::DEFAULT_VALUE)
35
35
  expect(hash[SecureHeaders::XPermittedCrossDomainPolicies::HEADER_NAME]).to eq(SecureHeaders::XPermittedCrossDomainPolicies::DEFAULT_VALUE)
36
36
  expect(hash[SecureHeaders::ReferrerPolicy::HEADER_NAME]).to be_nil
37
+ expect(hash[SecureHeaders::ExpectCertificateTransparency::HEADER_NAME]).to be_nil
37
38
  end
38
39
 
39
40
  module SecureHeaders
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.6.7
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Matatall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-14 00:00:00.000000000 Z
11
+ date: 2017-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -73,6 +73,7 @@ files:
73
73
  - lib/secure_headers/headers/content_security_policy.rb
74
74
  - lib/secure_headers/headers/content_security_policy_config.rb
75
75
  - lib/secure_headers/headers/cookie.rb
76
+ - lib/secure_headers/headers/expect_certificate_transparency.rb
76
77
  - lib/secure_headers/headers/policy_management.rb
77
78
  - lib/secure_headers/headers/public_key_pins.rb
78
79
  - lib/secure_headers/headers/referrer_policy.rb
@@ -92,6 +93,7 @@ files:
92
93
  - spec/lib/secure_headers/headers/clear_site_data_spec.rb
93
94
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
94
95
  - spec/lib/secure_headers/headers/cookie_spec.rb
96
+ - spec/lib/secure_headers/headers/expect_certificate_spec.rb
95
97
  - spec/lib/secure_headers/headers/policy_management_spec.rb
96
98
  - spec/lib/secure_headers/headers/public_key_pins_spec.rb
97
99
  - spec/lib/secure_headers/headers/referrer_policy_spec.rb
@@ -136,6 +138,7 @@ test_files:
136
138
  - spec/lib/secure_headers/headers/clear_site_data_spec.rb
137
139
  - spec/lib/secure_headers/headers/content_security_policy_spec.rb
138
140
  - spec/lib/secure_headers/headers/cookie_spec.rb
141
+ - spec/lib/secure_headers/headers/expect_certificate_spec.rb
139
142
  - spec/lib/secure_headers/headers/policy_management_spec.rb
140
143
  - spec/lib/secure_headers/headers/public_key_pins_spec.rb
141
144
  - spec/lib/secure_headers/headers/referrer_policy_spec.rb