secure_headers 6.4.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
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