secure_headers 3.6.7 → 3.7.0

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.

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