secure_headers 6.4.0 → 6.6.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/.github/dependabot.yml +6 -0
- data/.github/workflows/build.yml +3 -3
- data/.ruby-version +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +3 -1
- data/lib/secure_headers/headers/content_security_policy.rb +1 -19
- data/lib/secure_headers/headers/content_security_policy_config.rb +0 -1
- data/lib/secure_headers/headers/cookie.rb +2 -2
- data/lib/secure_headers/headers/policy_management.rb +3 -6
- data/lib/secure_headers/version.rb +1 -1
- data/secure_headers.gemspec +3 -3
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +15 -10
- data/spec/lib/secure_headers/headers/policy_management_spec.rb +5 -12
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2afd142dc54275ace387af0a964bba3918655513474a14f11959532616108d58
|
4
|
+
data.tar.gz: f520ab4f191710af2d78bc662319b02ab7819bba57a091c921822984393f18e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fe9df12ae44cabd372f84e8eebd47946e6102d8c920cf48752e3f36bcd1db3e429cbc47e54dda8f8194b4ae2cb90c583eec38b0e7906bac8f0fb9337eb7ecad
|
7
|
+
data.tar.gz: 56a30016b7f290693c89d8f8e2fd4e3d8425962a2dcb0fb75c96bd6b2fc8b85b890373a4ebd160e7cf2896e494697a563dd882f11f7527da9c29234d41bd2b17
|
data/.github/workflows/build.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
name: Build + Test
|
2
|
-
on: [pull_request]
|
2
|
+
on: [pull_request, push]
|
3
3
|
|
4
4
|
jobs:
|
5
5
|
build:
|
@@ -7,10 +7,10 @@ jobs:
|
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: [ '2.
|
10
|
+
ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2' ]
|
11
11
|
|
12
12
|
steps:
|
13
|
-
- uses: actions/checkout@
|
13
|
+
- uses: actions/checkout@v3
|
14
14
|
- name: Set up Ruby ${{ matrix.ruby }}
|
15
15
|
uses: ruby/setup-ruby@v1
|
16
16
|
with:
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 6.5.0
|
2
|
+
|
3
|
+
- CSP: Remove source expression deduplication. (@lgarron) https://github.com/github/secure_headers/pull/499
|
4
|
+
|
1
5
|
## 6.4.0
|
2
6
|
|
3
7
|
- CSP: Add support for trusted-types, require-trusted-types-for directive (@JackMc): https://github.com/github/secure_headers/pull/486
|
data/README.md
CHANGED
@@ -62,7 +62,6 @@ SecureHeaders::Configuration.default do |config|
|
|
62
62
|
# directive values: these values will directly translate into source directives
|
63
63
|
default_src: %w('none'),
|
64
64
|
base_uri: %w('self'),
|
65
|
-
block_all_mixed_content: true, # see https://www.w3.org/TR/mixed-content/
|
66
65
|
child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
|
67
66
|
connect_src: %w(wss:),
|
68
67
|
font_src: %w('self' data:),
|
@@ -92,6 +91,9 @@ SecureHeaders::Configuration.default do |config|
|
|
92
91
|
end
|
93
92
|
```
|
94
93
|
|
94
|
+
### Deprecated Configuration Values
|
95
|
+
* `block_all_mixed_content` - this value is deprecated in favor of `upgrade_insecure_requests`. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content for more information.
|
96
|
+
|
95
97
|
## Default values
|
96
98
|
|
97
99
|
All headers except for PublicKeyPins and ClearSiteData have a default value. The default set of headers is:
|
@@ -133,7 +133,7 @@ module SecureHeaders
|
|
133
133
|
unless directive == REPORT_URI || @preserve_schemes
|
134
134
|
source_list = strip_source_schemes(source_list)
|
135
135
|
end
|
136
|
-
|
136
|
+
source_list.uniq
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -151,24 +151,6 @@ module SecureHeaders
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
# Removes duplicates and sources that already match an existing wild card.
|
155
|
-
#
|
156
|
-
# e.g. *.github.com asdf.github.com becomes *.github.com
|
157
|
-
def dedup_source_list(sources)
|
158
|
-
sources = sources.uniq
|
159
|
-
wild_sources = sources.select { |source| source =~ STAR_REGEXP }
|
160
|
-
|
161
|
-
if wild_sources.any?
|
162
|
-
schemes = sources.map { |source| [source, URI(source).scheme] }.to_h
|
163
|
-
sources.reject do |source|
|
164
|
-
!wild_sources.include?(source) &&
|
165
|
-
wild_sources.any? { |pattern| schemes[pattern] == schemes[source] && File.fnmatch(pattern, source) }
|
166
|
-
end
|
167
|
-
else
|
168
|
-
sources
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
154
|
# Private: append a nonce to the script/style directories if script_nonce
|
173
155
|
# or style_nonce are provided.
|
174
156
|
def populate_nonces(directive, source_list)
|
@@ -80,9 +80,9 @@ module SecureHeaders
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def conditionally_flag?(configuration)
|
83
|
-
if(Array(configuration[:only]).any? && (Array(configuration[:only]) & parsed_cookie.keys).any?)
|
83
|
+
if (Array(configuration[:only]).any? && (Array(configuration[:only]) & parsed_cookie.keys).any?)
|
84
84
|
true
|
85
|
-
elsif(Array(configuration[:except]).any? && (Array(configuration[:except]) & parsed_cookie.keys).none?)
|
85
|
+
elsif (Array(configuration[:except]).any? && (Array(configuration[:except]) & parsed_cookie.keys).none?)
|
86
86
|
true
|
87
87
|
else
|
88
88
|
false
|
@@ -71,7 +71,6 @@ module SecureHeaders
|
|
71
71
|
|
72
72
|
# All the directives currently under consideration for CSP level 3.
|
73
73
|
# https://w3c.github.io/webappsec/specs/CSP2/
|
74
|
-
BLOCK_ALL_MIXED_CONTENT = :block_all_mixed_content
|
75
74
|
MANIFEST_SRC = :manifest_src
|
76
75
|
NAVIGATE_TO = :navigate_to
|
77
76
|
PREFETCH_SRC = :prefetch_src
|
@@ -85,7 +84,6 @@ module SecureHeaders
|
|
85
84
|
|
86
85
|
DIRECTIVES_3_0 = [
|
87
86
|
DIRECTIVES_2_0,
|
88
|
-
BLOCK_ALL_MIXED_CONTENT,
|
89
87
|
MANIFEST_SRC,
|
90
88
|
NAVIGATE_TO,
|
91
89
|
PREFETCH_SRC,
|
@@ -118,7 +116,6 @@ module SecureHeaders
|
|
118
116
|
|
119
117
|
DIRECTIVE_VALUE_TYPES = {
|
120
118
|
BASE_URI => :source_list,
|
121
|
-
BLOCK_ALL_MIXED_CONTENT => :boolean,
|
122
119
|
CHILD_SRC => :source_list,
|
123
120
|
CONNECT_SRC => :source_list,
|
124
121
|
DEFAULT_SRC => :source_list,
|
@@ -189,7 +186,7 @@ module SecureHeaders
|
|
189
186
|
].freeze
|
190
187
|
|
191
188
|
REQUIRE_SRI_FOR_VALUES = Set.new(%w(script style))
|
192
|
-
REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set.new(%w(script))
|
189
|
+
REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set.new(%w('script'))
|
193
190
|
|
194
191
|
module ClassMethods
|
195
192
|
# Public: generate a header name, value array that is user-agent-aware.
|
@@ -241,7 +238,7 @@ module SecureHeaders
|
|
241
238
|
#
|
242
239
|
# raises an error if the original config is OPT_OUT
|
243
240
|
#
|
244
|
-
# 1. for non-source-list values (report_only,
|
241
|
+
# 1. for non-source-list values (report_only, upgrade_insecure_requests),
|
245
242
|
# additions will overwrite the original value.
|
246
243
|
# 2. if a value in additions does not exist in the original config, the
|
247
244
|
# default-src value is included to match original behavior.
|
@@ -393,7 +390,7 @@ module SecureHeaders
|
|
393
390
|
|
394
391
|
# Private: validates that a require trusted types for expression:
|
395
392
|
# 1. is an array of strings
|
396
|
-
# 2. is a subset of ["script"]
|
393
|
+
# 2. is a subset of ["'script'"]
|
397
394
|
def validate_require_trusted_types_for_source_expression!(directive, require_trusted_types_for_expression)
|
398
395
|
ensure_array_of_strings!(directive, require_trusted_types_for_expression)
|
399
396
|
unless require_trusted_types_for_expression.to_set.subset?(REQUIRE_TRUSTED_TYPES_FOR_VALUES)
|
data/secure_headers.gemspec
CHANGED
@@ -9,12 +9,12 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.version = SecureHeaders::VERSION
|
10
10
|
gem.authors = ["Neil Matatall"]
|
11
11
|
gem.email = ["neil.matatall@gmail.com"]
|
12
|
-
gem.
|
13
|
-
gem.
|
12
|
+
gem.summary = "Manages application of security headers with many safe defaults."
|
13
|
+
gem.description = 'Add easily configured security headers to responses
|
14
14
|
including content-security-policy, x-frame-options,
|
15
15
|
strict-transport-security, etc.'
|
16
16
|
gem.homepage = "https://github.com/twitter/secureheaders"
|
17
|
-
gem.license = "
|
17
|
+
gem.license = "MIT"
|
18
18
|
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
19
19
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
20
20
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -48,12 +48,12 @@ module SecureHeaders
|
|
48
48
|
expect(csp.value).to eq("default-src * 'unsafe-inline' 'unsafe-eval' data: blob:")
|
49
49
|
end
|
50
50
|
|
51
|
-
it "
|
51
|
+
it "does not minify source expressions based on overlapping wildcards" do
|
52
52
|
config = {
|
53
53
|
default_src: %w(a.example.org b.example.org *.example.org https://*.example.org)
|
54
54
|
}
|
55
55
|
csp = ContentSecurityPolicy.new(config)
|
56
|
-
expect(csp.value).to eq("default-src *.example.org")
|
56
|
+
expect(csp.value).to eq("default-src a.example.org b.example.org *.example.org")
|
57
57
|
end
|
58
58
|
|
59
59
|
it "removes http/s schemes from hosts" do
|
@@ -92,17 +92,22 @@ module SecureHeaders
|
|
92
92
|
end
|
93
93
|
|
94
94
|
it "does add a boolean directive if the value is true" do
|
95
|
-
csp = ContentSecurityPolicy.new(default_src: ["https://example.org"],
|
96
|
-
expect(csp.value).to eq("default-src example.org;
|
95
|
+
csp = ContentSecurityPolicy.new(default_src: ["https://example.org"], upgrade_insecure_requests: true)
|
96
|
+
expect(csp.value).to eq("default-src example.org; upgrade-insecure-requests")
|
97
97
|
end
|
98
98
|
|
99
99
|
it "does not add a boolean directive if the value is false" do
|
100
|
-
csp = ContentSecurityPolicy.new(default_src: ["https://example.org"],
|
101
|
-
expect(csp.value).to eq("default-src example.org
|
100
|
+
csp = ContentSecurityPolicy.new(default_src: ["https://example.org"], upgrade_insecure_requests: false)
|
101
|
+
expect(csp.value).to eq("default-src example.org")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "handles wildcard subdomain with wildcard port" do
|
105
|
+
csp = ContentSecurityPolicy.new(default_src: %w(https://*.example.org:*))
|
106
|
+
expect(csp.value).to eq("default-src *.example.org:*")
|
102
107
|
end
|
103
108
|
|
104
|
-
it "deduplicates
|
105
|
-
csp = ContentSecurityPolicy.new(default_src: %w(example.org example.org example.org))
|
109
|
+
it "deduplicates source expressions that match exactly (after scheme stripping)" do
|
110
|
+
csp = ContentSecurityPolicy.new(default_src: %w(example.org https://example.org example.org))
|
106
111
|
expect(csp.value).to eq("default-src example.org")
|
107
112
|
end
|
108
113
|
|
@@ -197,8 +202,8 @@ module SecureHeaders
|
|
197
202
|
end
|
198
203
|
|
199
204
|
it "supports trusted-types directive with 'none'" do
|
200
|
-
csp = ContentSecurityPolicy.new({trusted_types: %w(none)})
|
201
|
-
expect(csp.value).to eq("trusted-types none")
|
205
|
+
csp = ContentSecurityPolicy.new({trusted_types: %w('none')})
|
206
|
+
expect(csp.value).to eq("trusted-types 'none'")
|
202
207
|
end
|
203
208
|
|
204
209
|
it "allows duplicate policy names in trusted-types directive" do
|
@@ -30,7 +30,6 @@ module SecureHeaders
|
|
30
30
|
default_src: %w(https: 'self'),
|
31
31
|
|
32
32
|
base_uri: %w('self'),
|
33
|
-
block_all_mixed_content: true, # see [http://www.w3.org/TR/mixed-content/](http://www.w3.org/TR/mixed-content/)
|
34
33
|
connect_src: %w(wss:),
|
35
34
|
child_src: %w('self' *.twimg.com itunes.apple.com),
|
36
35
|
font_src: %w('self' data:),
|
@@ -45,7 +44,7 @@ module SecureHeaders
|
|
45
44
|
plugin_types: %w(application/x-shockwave-flash),
|
46
45
|
prefetch_src: %w(fetch.com),
|
47
46
|
require_sri_for: %w(script style),
|
48
|
-
require_trusted_types_for: %w(script),
|
47
|
+
require_trusted_types_for: %w('script'),
|
49
48
|
script_src: %w('self'),
|
50
49
|
style_src: %w('unsafe-inline'),
|
51
50
|
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
|
@@ -92,12 +91,6 @@ module SecureHeaders
|
|
92
91
|
end.to raise_error(ContentSecurityPolicyConfigError)
|
93
92
|
end
|
94
93
|
|
95
|
-
it "requires :block_all_mixed_content to be a boolean value" do
|
96
|
-
expect do
|
97
|
-
ContentSecurityPolicy.validate_config!(ContentSecurityPolicyConfig.new(default_opts.merge(block_all_mixed_content: "steve")))
|
98
|
-
end.to raise_error(ContentSecurityPolicyConfigError)
|
99
|
-
end
|
100
|
-
|
101
94
|
it "requires :upgrade_insecure_requests to be a boolean value" do
|
102
95
|
expect do
|
103
96
|
ContentSecurityPolicy.validate_config!(ContentSecurityPolicyConfig.new(default_opts.merge(upgrade_insecure_requests: "steve")))
|
@@ -244,18 +237,18 @@ module SecureHeaders
|
|
244
237
|
expect(csp.name).to eq(ContentSecurityPolicyReportOnlyConfig::HEADER_NAME)
|
245
238
|
end
|
246
239
|
|
247
|
-
it "overrides the :
|
240
|
+
it "overrides the :upgrade_insecure_requests flag" do
|
248
241
|
Configuration.default do |config|
|
249
242
|
config.csp = {
|
250
243
|
default_src: %w(https:),
|
251
244
|
script_src: %w('self'),
|
252
|
-
|
245
|
+
upgrade_insecure_requests: false
|
253
246
|
}
|
254
247
|
end
|
255
248
|
default_policy = Configuration.dup
|
256
|
-
combined_config = ContentSecurityPolicy.combine_policies(default_policy.csp.to_h,
|
249
|
+
combined_config = ContentSecurityPolicy.combine_policies(default_policy.csp.to_h, upgrade_insecure_requests: true)
|
257
250
|
csp = ContentSecurityPolicy.new(combined_config)
|
258
|
-
expect(csp.value).to eq("default-src https:;
|
251
|
+
expect(csp.value).to eq("default-src https:; script-src 'self'; upgrade-insecure-requests")
|
259
252
|
end
|
260
253
|
|
261
254
|
it "raises an error if appending to a OPT_OUT policy" do
|
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: 6.
|
4
|
+
version: 6.6.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:
|
11
|
+
date: 2024-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -24,7 +24,10 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description: |-
|
28
|
+
Add easily configured security headers to responses
|
29
|
+
including content-security-policy, x-frame-options,
|
30
|
+
strict-transport-security, etc.
|
28
31
|
email:
|
29
32
|
- neil.matatall@gmail.com
|
30
33
|
executables: []
|
@@ -33,6 +36,7 @@ extra_rdoc_files: []
|
|
33
36
|
files:
|
34
37
|
- ".github/ISSUE_TEMPLATE.md"
|
35
38
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
39
|
+
- ".github/dependabot.yml"
|
36
40
|
- ".github/workflows/build.yml"
|
37
41
|
- ".github/workflows/github-release.yml"
|
38
42
|
- ".gitignore"
|
@@ -99,7 +103,7 @@ files:
|
|
99
103
|
- spec/spec_helper.rb
|
100
104
|
homepage: https://github.com/twitter/secureheaders
|
101
105
|
licenses:
|
102
|
-
-
|
106
|
+
- MIT
|
103
107
|
metadata: {}
|
104
108
|
post_install_message:
|
105
109
|
rdoc_options: []
|
@@ -116,11 +120,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
120
|
- !ruby/object:Gem::Version
|
117
121
|
version: '0'
|
118
122
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
123
|
+
rubygems_version: 3.0.3.1
|
120
124
|
signing_key:
|
121
125
|
specification_version: 4
|
122
|
-
summary:
|
123
|
-
x-frame-options, strict-transport-security, etc.
|
126
|
+
summary: Manages application of security headers with many safe defaults.
|
124
127
|
test_files:
|
125
128
|
- spec/lib/secure_headers/configuration_spec.rb
|
126
129
|
- spec/lib/secure_headers/headers/clear_site_data_spec.rb
|