secure_headers 3.6.5 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +7 -0
- data/lib/secure_headers/configuration.rb +4 -1
- data/lib/secure_headers/headers/content_security_policy_config.rb +0 -1
- data/lib/secure_headers/headers/expect_certificate_transparency.rb +70 -0
- data/lib/secure_headers/headers/policy_management.rb +8 -16
- data/lib/secure_headers.rb +2 -0
- data/secure_headers.gemspec +1 -1
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +5 -6
- data/spec/lib/secure_headers/headers/expect_certificate_spec.rb +42 -0
- data/spec/lib/secure_headers/headers/policy_management_spec.rb +1 -0
- data/spec/spec_helper.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 591de0f41bc64b3520fbb2fdab9fc94b490d1604
|
|
4
|
+
data.tar.gz: f836c5e63e4d054ff2ce3f1ec597bbd9cf67ed4b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5317d425d7c65dfc73b32703aae7e16e3a566b620b42e3233cd6dc7403a1a9842bb7dc00ffc5c13a86240c5a8abee3ae07fed0c73d4b06a06bcc11db39a79a20
|
|
7
|
+
data.tar.gz: 154573bfb9112b4b1510abbde3f5eb1e85b709f7839ff4a6a547223e67e698ff014bb578f02b0e8775ee723016f5903e8cda38cb9846b24cafe3dc8e414bb007
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 3.7.0
|
|
2
|
+
|
|
3
|
+
Adds support for the `Expect-CT` header (@jacobbednarz: https://github.com/twitter/secureheaders/pull/322)
|
|
4
|
+
|
|
5
|
+
## 3.6.7
|
|
6
|
+
|
|
7
|
+
Actually set manifest-src when configured. https://github.com/twitter/secureheaders/pull/339 Thanks @carlosantoniodasilva!
|
|
8
|
+
|
|
9
|
+
## 3.6.6
|
|
10
|
+
|
|
11
|
+
wat?
|
|
12
|
+
|
|
1
13
|
## 3.6.5
|
|
2
14
|
|
|
3
15
|
Update clear-site-data header to use current format specified by the specification.
|
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]
|
|
@@ -91,6 +97,7 @@ SecureHeaders::Configuration.default do |config|
|
|
|
91
97
|
form_action: %w('self' github.com),
|
|
92
98
|
frame_ancestors: %w('none'),
|
|
93
99
|
img_src: %w(mycdn.com data:),
|
|
100
|
+
manifest_src: %w('self'),
|
|
94
101
|
media_src: %w(utoob.com),
|
|
95
102
|
object_src: %w('self'),
|
|
96
103
|
plugin_types: %w(application/x-shockwave-flash),
|
|
@@ -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
|
|
@@ -62,22 +62,15 @@ module SecureHeaders
|
|
|
62
62
|
|
|
63
63
|
# All the directives currently under consideration for CSP level 3.
|
|
64
64
|
# https://w3c.github.io/webappsec/specs/CSP2/
|
|
65
|
+
BLOCK_ALL_MIXED_CONTENT = :block_all_mixed_content
|
|
65
66
|
MANIFEST_SRC = :manifest_src
|
|
66
|
-
|
|
67
|
+
UPGRADE_INSECURE_REQUESTS = :upgrade_insecure_requests
|
|
67
68
|
DIRECTIVES_3_0 = [
|
|
68
69
|
DIRECTIVES_2_0,
|
|
69
|
-
MANIFEST_SRC,
|
|
70
|
-
REFLECTED_XSS
|
|
71
|
-
].flatten.freeze
|
|
72
|
-
|
|
73
|
-
# All the directives that are not currently in a formal spec, but have
|
|
74
|
-
# been implemented somewhere.
|
|
75
|
-
BLOCK_ALL_MIXED_CONTENT = :block_all_mixed_content
|
|
76
|
-
UPGRADE_INSECURE_REQUESTS = :upgrade_insecure_requests
|
|
77
|
-
DIRECTIVES_DRAFT = [
|
|
78
70
|
BLOCK_ALL_MIXED_CONTENT,
|
|
71
|
+
MANIFEST_SRC,
|
|
79
72
|
UPGRADE_INSECURE_REQUESTS
|
|
80
|
-
].freeze
|
|
73
|
+
].flatten.freeze
|
|
81
74
|
|
|
82
75
|
EDGE_DIRECTIVES = DIRECTIVES_1_0
|
|
83
76
|
SAFARI_DIRECTIVES = DIRECTIVES_1_0
|
|
@@ -99,18 +92,18 @@ module SecureHeaders
|
|
|
99
92
|
].freeze
|
|
100
93
|
|
|
101
94
|
FIREFOX_DIRECTIVES = (
|
|
102
|
-
|
|
95
|
+
DIRECTIVES_3_0 - FIREFOX_UNSUPPORTED_DIRECTIVES
|
|
103
96
|
).freeze
|
|
104
97
|
|
|
105
98
|
FIREFOX_46_DIRECTIVES = (
|
|
106
|
-
|
|
99
|
+
DIRECTIVES_3_0 - FIREFOX_46_UNSUPPORTED_DIRECTIVES - FIREFOX_46_DEPRECATED_DIRECTIVES
|
|
107
100
|
).freeze
|
|
108
101
|
|
|
109
102
|
CHROME_DIRECTIVES = (
|
|
110
|
-
|
|
103
|
+
DIRECTIVES_3_0
|
|
111
104
|
).freeze
|
|
112
105
|
|
|
113
|
-
ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0
|
|
106
|
+
ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0).uniq.sort
|
|
114
107
|
|
|
115
108
|
# Think of default-src and report-uri as the beginning and end respectively,
|
|
116
109
|
# everything else is in between.
|
|
@@ -156,7 +149,6 @@ module SecureHeaders
|
|
|
156
149
|
MEDIA_SRC => :source_list,
|
|
157
150
|
OBJECT_SRC => :source_list,
|
|
158
151
|
PLUGIN_TYPES => :source_list,
|
|
159
|
-
REFLECTED_XSS => :string,
|
|
160
152
|
REPORT_URI => :source_list,
|
|
161
153
|
SANDBOX => :source_list,
|
|
162
154
|
SCRIPT_SRC => :source_list,
|
data/lib/secure_headers.rb
CHANGED
|
@@ -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,
|
data/secure_headers.gemspec
CHANGED
|
@@ -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.
|
|
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.'
|
|
@@ -119,7 +119,6 @@ module SecureHeaders
|
|
|
119
119
|
end.merge({
|
|
120
120
|
block_all_mixed_content: true,
|
|
121
121
|
upgrade_insecure_requests: true,
|
|
122
|
-
reflected_xss: "block",
|
|
123
122
|
script_src: %w(script-src.com),
|
|
124
123
|
script_nonce: 123456
|
|
125
124
|
})
|
|
@@ -127,22 +126,22 @@ module SecureHeaders
|
|
|
127
126
|
|
|
128
127
|
it "does not filter any directives for Chrome" do
|
|
129
128
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:chrome])
|
|
130
|
-
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
129
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; manifest-src manifest-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
131
130
|
end
|
|
132
131
|
|
|
133
132
|
it "does not filter any directives for Opera" do
|
|
134
133
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:opera])
|
|
135
|
-
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
134
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; manifest-src manifest-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
136
135
|
end
|
|
137
136
|
|
|
138
137
|
it "filters blocked-all-mixed-content, child-src, and plugin-types for firefox" do
|
|
139
138
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox])
|
|
140
|
-
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
139
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; manifest-src manifest-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
141
140
|
end
|
|
142
141
|
|
|
143
142
|
it "filters blocked-all-mixed-content, frame-src, and plugin-types for firefox 46 and higher" do
|
|
144
143
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox46])
|
|
145
|
-
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
144
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; manifest-src manifest-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
146
145
|
end
|
|
147
146
|
|
|
148
147
|
it "child-src value is copied to frame-src, adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for Edge" do
|
|
@@ -164,7 +163,7 @@ module SecureHeaders
|
|
|
164
163
|
ua = USER_AGENTS[:firefox].dup
|
|
165
164
|
allow(ua).to receive(:version).and_return(nil)
|
|
166
165
|
policy = ContentSecurityPolicy.new(complex_opts, ua)
|
|
167
|
-
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
166
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; manifest-src manifest-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
|
168
167
|
end
|
|
169
168
|
end
|
|
170
169
|
end
|
|
@@ -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.
|
|
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-
|
|
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
|