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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5372953d5180d45526a777c1b66e7e86a8ccfca08f6b7b613549d8ba1509a6e
4
- data.tar.gz: 0d1cc3b012df7b1cfd549bcf09063a390945b05c03009acda31017f859ff7d2d
3
+ metadata.gz: 2afd142dc54275ace387af0a964bba3918655513474a14f11959532616108d58
4
+ data.tar.gz: f520ab4f191710af2d78bc662319b02ab7819bba57a091c921822984393f18e5
5
5
  SHA512:
6
- metadata.gz: 35844f24ecb678a83548492545403bc174a6d0ce74896f7817d93cb30f62d97b415ea876dccd3efbed7cad3e5dd5c9cda4f676f7dc2c858b2f2010f2c33a0f73
7
- data.tar.gz: 196a212de355c06a2a3fee6c22302fb1bfd7471dba402124adc7072f90dbd0c4a5b3ee8fa7604d0b164479717bfb65050d3b4802948410b61aba3382d5c8eb39
6
+ metadata.gz: 3fe9df12ae44cabd372f84e8eebd47946e6102d8c920cf48752e3f36bcd1db3e429cbc47e54dda8f8194b4ae2cb90c583eec38b0e7906bac8f0fb9337eb7ecad
7
+ data.tar.gz: 56a30016b7f290693c89d8f8e2fd4e3d8425962a2dcb0fb75c96bd6b2fc8b85b890373a4ebd160e7cf2896e494697a563dd882f11f7527da9c29234d41bd2b17
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
@@ -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.5', '2.6', '2.7', '3.0', '3.1' ]
10
+ ruby: [ '2.6', '2.7', '3.0', '3.1', '3.2' ]
11
11
 
12
12
  steps:
13
- - uses: actions/checkout@v2
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
- 2.6.6
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
- dedup_source_list(source_list)
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)
@@ -16,7 +16,6 @@ module SecureHeaders
16
16
 
17
17
  def initialize(hash)
18
18
  @base_uri = nil
19
- @block_all_mixed_content = nil
20
19
  @child_src = nil
21
20
  @connect_src = nil
22
21
  @default_src = nil
@@ -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, block_all_mixed_content, upgrade_insecure_requests),
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecureHeaders
4
- VERSION = "6.4.0"
4
+ VERSION = "6.6.0"
5
5
  end
@@ -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.description = "Manages application of security headers with many safe defaults."
13
- gem.summary = 'Add easily configured security headers to responses
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 = "Apache Public License 2.0"
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 "minifies source expressions based on overlapping wildcards" do
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"], block_all_mixed_content: true, upgrade_insecure_requests: true)
96
- expect(csp.value).to eq("default-src example.org; block-all-mixed-content; upgrade-insecure-requests")
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"], block_all_mixed_content: true, upgrade_insecure_requests: false)
101
- expect(csp.value).to eq("default-src example.org; block-all-mixed-content")
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 any source expressions" do
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 :block_all_mixed_content flag" do
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
- block_all_mixed_content: false
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, block_all_mixed_content: true)
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:; block-all-mixed-content; script-src 'self'")
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.0
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: 2022-08-02 00:00:00.000000000 Z
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: Manages application of security headers with many safe defaults.
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
- - Apache Public License 2.0
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.2.9
123
+ rubygems_version: 3.0.3.1
120
124
  signing_key:
121
125
  specification_version: 4
122
- summary: Add easily configured security headers to responses including content-security-policy,
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