secure_headers 6.3.4 → 6.5.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/workflows/build.yml +2 -2
- data/.ruby-version +1 -1
- data/CHANGELOG.md +8 -0
- data/lib/secure_headers/configuration.rb +6 -5
- data/lib/secure_headers/headers/content_security_policy.rb +20 -34
- data/lib/secure_headers/headers/content_security_policy_config.rb +2 -0
- data/lib/secure_headers/headers/policy_management.rb +40 -7
- data/lib/secure_headers/version.rb +1 -1
- data/lib/secure_headers/view_helper.rb +7 -6
- data/secure_headers.gemspec +3 -3
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +29 -4
- data/spec/lib/secure_headers/headers/policy_management_spec.rb +8 -0
- data/spec/lib/secure_headers/view_helpers_spec.rb +5 -4
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bafd5e6390db0f1975599ab34f1293986a5c0a1ced14f6cfeca47fd114ce87d4
|
4
|
+
data.tar.gz: 177dc27fa8238fe1a8baa238f6baa244b2c03393f61269e9b417e5ea3a4a4bba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a24f853958892e2780dec3cfd8f631d394c959cda6d3f8be5d701792fc1ce57d4141ca88e7b0980fcac979cc855a0c5bc9165a05b314fe281ce092a438f1fe1
|
7
|
+
data.tar.gz: c082a3ee192452712f8e9c7ed18d5c21b5b3eb1712c3d9a4df44220093cf1be09a8e5384f5c8a8909820f1e0048c6d3b6915cc29081288bcf13361bf8cf7dbed
|
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,7 +7,7 @@ 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' ]
|
11
11
|
|
12
12
|
steps:
|
13
13
|
- uses: actions/checkout@v2
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.1.1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 6.5.0
|
2
|
+
|
3
|
+
- CSP: Remove source expression deduplication. (@lgarron) https://github.com/github/secure_headers/pull/499
|
4
|
+
|
5
|
+
## 6.4.0
|
6
|
+
|
7
|
+
- CSP: Add support for trusted-types, require-trusted-types-for directive (@JackMc): https://github.com/github/secure_headers/pull/486
|
8
|
+
|
1
9
|
## 6.3.4
|
2
10
|
|
3
11
|
- CSP: Do not deduplicate alternate schema source expressions (@keithamus): https://github.com/github/secure_headers/pull/478
|
@@ -84,11 +84,12 @@ module SecureHeaders
|
|
84
84
|
def deep_copy(config)
|
85
85
|
return unless config
|
86
86
|
config.each_with_object({}) do |(key, value), hash|
|
87
|
-
hash[key] =
|
88
|
-
value.
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
hash[key] =
|
88
|
+
if value.is_a?(Array)
|
89
|
+
value.dup
|
90
|
+
else
|
91
|
+
value
|
92
|
+
end
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
@@ -7,17 +7,18 @@ module SecureHeaders
|
|
7
7
|
include PolicyManagement
|
8
8
|
|
9
9
|
def initialize(config = nil)
|
10
|
-
@config =
|
11
|
-
if config
|
12
|
-
|
10
|
+
@config =
|
11
|
+
if config.is_a?(Hash)
|
12
|
+
if config[:report_only]
|
13
|
+
ContentSecurityPolicyReportOnlyConfig.new(config || DEFAULT_CONFIG)
|
14
|
+
else
|
15
|
+
ContentSecurityPolicyConfig.new(config || DEFAULT_CONFIG)
|
16
|
+
end
|
17
|
+
elsif config.nil?
|
18
|
+
ContentSecurityPolicyConfig.new(DEFAULT_CONFIG)
|
13
19
|
else
|
14
|
-
|
20
|
+
config
|
15
21
|
end
|
16
|
-
elsif config.nil?
|
17
|
-
ContentSecurityPolicyConfig.new(DEFAULT_CONFIG)
|
18
|
-
else
|
19
|
-
config
|
20
|
-
end
|
21
22
|
|
22
23
|
@preserve_schemes = @config.preserve_schemes
|
23
24
|
@script_nonce = @config.script_nonce
|
@@ -34,11 +35,12 @@ module SecureHeaders
|
|
34
35
|
##
|
35
36
|
# Return the value of the CSP header
|
36
37
|
def value
|
37
|
-
@value ||=
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
@value ||=
|
39
|
+
if @config
|
40
|
+
build_value
|
41
|
+
else
|
42
|
+
DEFAULT_VALUE
|
43
|
+
end
|
42
44
|
end
|
43
45
|
|
44
46
|
private
|
@@ -51,7 +53,9 @@ module SecureHeaders
|
|
51
53
|
def build_value
|
52
54
|
directives.map do |directive_name|
|
53
55
|
case DIRECTIVE_VALUE_TYPES[directive_name]
|
54
|
-
when :source_list,
|
56
|
+
when :source_list,
|
57
|
+
:require_sri_for_list, # require_sri is a simple set of strings that don't need to deal with symbol casing
|
58
|
+
:require_trusted_types_for_list
|
55
59
|
build_source_list_directive(directive_name)
|
56
60
|
when :boolean
|
57
61
|
symbol_to_hyphen_case(directive_name) if @config.directive_value(directive_name)
|
@@ -129,7 +133,7 @@ module SecureHeaders
|
|
129
133
|
unless directive == REPORT_URI || @preserve_schemes
|
130
134
|
source_list = strip_source_schemes(source_list)
|
131
135
|
end
|
132
|
-
|
136
|
+
source_list.uniq
|
133
137
|
end
|
134
138
|
end
|
135
139
|
|
@@ -147,24 +151,6 @@ module SecureHeaders
|
|
147
151
|
end
|
148
152
|
end
|
149
153
|
|
150
|
-
# Removes duplicates and sources that already match an existing wild card.
|
151
|
-
#
|
152
|
-
# e.g. *.github.com asdf.github.com becomes *.github.com
|
153
|
-
def dedup_source_list(sources)
|
154
|
-
sources = sources.uniq
|
155
|
-
wild_sources = sources.select { |source| source =~ STAR_REGEXP }
|
156
|
-
|
157
|
-
if wild_sources.any?
|
158
|
-
schemes = sources.map { |source| [source, URI(source).scheme] }.to_h
|
159
|
-
sources.reject do |source|
|
160
|
-
!wild_sources.include?(source) &&
|
161
|
-
wild_sources.any? { |pattern| schemes[pattern] == schemes[source] && File.fnmatch(pattern, source) }
|
162
|
-
end
|
163
|
-
else
|
164
|
-
sources
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
154
|
# Private: append a nonce to the script/style directories if script_nonce
|
169
155
|
# or style_nonce are provided.
|
170
156
|
def populate_nonces(directive, source_list)
|
@@ -35,6 +35,7 @@ module SecureHeaders
|
|
35
35
|
@report_only = nil
|
36
36
|
@report_uri = nil
|
37
37
|
@require_sri_for = nil
|
38
|
+
@require_trusted_types_for = nil
|
38
39
|
@sandbox = nil
|
39
40
|
@script_nonce = nil
|
40
41
|
@script_src = nil
|
@@ -44,6 +45,7 @@ module SecureHeaders
|
|
44
45
|
@style_src = nil
|
45
46
|
@style_src_elem = nil
|
46
47
|
@style_src_attr = nil
|
48
|
+
@trusted_types = nil
|
47
49
|
@worker_src = nil
|
48
50
|
@upgrade_insecure_requests = nil
|
49
51
|
@disable_nonce_backwards_compatibility = nil
|
@@ -98,7 +98,19 @@ module SecureHeaders
|
|
98
98
|
STYLE_SRC_ATTR
|
99
99
|
].flatten.freeze
|
100
100
|
|
101
|
-
|
101
|
+
# Experimental directives - these vary greatly in support
|
102
|
+
# See MDN for details.
|
103
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
|
104
|
+
TRUSTED_TYPES = :trusted_types
|
105
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for
|
106
|
+
REQUIRE_TRUSTED_TYPES_FOR = :require_trusted_types_for
|
107
|
+
|
108
|
+
DIRECTIVES_EXPERIMENTAL = [
|
109
|
+
TRUSTED_TYPES,
|
110
|
+
REQUIRE_TRUSTED_TYPES_FOR,
|
111
|
+
].flatten.freeze
|
112
|
+
|
113
|
+
ALL_DIRECTIVES = (DIRECTIVES_1_0 + DIRECTIVES_2_0 + DIRECTIVES_3_0 + DIRECTIVES_EXPERIMENTAL).uniq.sort
|
102
114
|
|
103
115
|
# Think of default-src and report-uri as the beginning and end respectively,
|
104
116
|
# everything else is in between.
|
@@ -121,6 +133,7 @@ module SecureHeaders
|
|
121
133
|
OBJECT_SRC => :source_list,
|
122
134
|
PLUGIN_TYPES => :media_type_list,
|
123
135
|
REQUIRE_SRI_FOR => :require_sri_for_list,
|
136
|
+
REQUIRE_TRUSTED_TYPES_FOR => :require_trusted_types_for_list,
|
124
137
|
REPORT_URI => :source_list,
|
125
138
|
PREFETCH_SRC => :source_list,
|
126
139
|
SANDBOX => :sandbox_list,
|
@@ -130,6 +143,7 @@ module SecureHeaders
|
|
130
143
|
STYLE_SRC => :source_list,
|
131
144
|
STYLE_SRC_ELEM => :source_list,
|
132
145
|
STYLE_SRC_ATTR => :source_list,
|
146
|
+
TRUSTED_TYPES => :source_list,
|
133
147
|
WORKER_SRC => :source_list,
|
134
148
|
UPGRADE_INSECURE_REQUESTS => :boolean,
|
135
149
|
}.freeze
|
@@ -175,6 +189,7 @@ module SecureHeaders
|
|
175
189
|
].freeze
|
176
190
|
|
177
191
|
REQUIRE_SRI_FOR_VALUES = Set.new(%w(script style))
|
192
|
+
REQUIRE_TRUSTED_TYPES_FOR_VALUES = Set.new(%w('script'))
|
178
193
|
|
179
194
|
module ClassMethods
|
180
195
|
# Public: generate a header name, value array that is user-agent-aware.
|
@@ -270,7 +285,8 @@ module SecureHeaders
|
|
270
285
|
source_list?(directive) ||
|
271
286
|
sandbox_list?(directive) ||
|
272
287
|
media_type_list?(directive) ||
|
273
|
-
require_sri_for_list?(directive)
|
288
|
+
require_sri_for_list?(directive) ||
|
289
|
+
require_trusted_types_for_list?(directive)
|
274
290
|
end
|
275
291
|
|
276
292
|
# For each directive in additions that does not exist in the original config,
|
@@ -278,11 +294,12 @@ module SecureHeaders
|
|
278
294
|
def populate_fetch_source_with_default!(original, additions)
|
279
295
|
# in case we would be appending to an empty directive, fill it with the default-src value
|
280
296
|
additions.each_key do |directive|
|
281
|
-
directive =
|
282
|
-
directive.to_s.
|
283
|
-
|
284
|
-
|
285
|
-
|
297
|
+
directive =
|
298
|
+
if directive.to_s.end_with?("_nonce")
|
299
|
+
directive.to_s.gsub(/_nonce/, "_src").to_sym
|
300
|
+
else
|
301
|
+
directive
|
302
|
+
end
|
286
303
|
# Don't set a default if directive has an existing value
|
287
304
|
next if original[directive]
|
288
305
|
if FETCH_SOURCES.include?(directive)
|
@@ -307,6 +324,10 @@ module SecureHeaders
|
|
307
324
|
DIRECTIVE_VALUE_TYPES[directive] == :require_sri_for_list
|
308
325
|
end
|
309
326
|
|
327
|
+
def require_trusted_types_for_list?(directive)
|
328
|
+
DIRECTIVE_VALUE_TYPES[directive] == :require_trusted_types_for_list
|
329
|
+
end
|
330
|
+
|
310
331
|
# Private: Validates that the configuration has a valid type, or that it is a valid
|
311
332
|
# source expression.
|
312
333
|
def validate_directive!(directive, value)
|
@@ -324,6 +345,8 @@ module SecureHeaders
|
|
324
345
|
validate_media_type_expression!(directive, value)
|
325
346
|
when :require_sri_for_list
|
326
347
|
validate_require_sri_source_expression!(directive, value)
|
348
|
+
when :require_trusted_types_for_list
|
349
|
+
validate_require_trusted_types_for_source_expression!(directive, value)
|
327
350
|
else
|
328
351
|
raise ContentSecurityPolicyConfigError.new("Unknown directive #{directive}")
|
329
352
|
end
|
@@ -368,6 +391,16 @@ module SecureHeaders
|
|
368
391
|
end
|
369
392
|
end
|
370
393
|
|
394
|
+
# Private: validates that a require trusted types for expression:
|
395
|
+
# 1. is an array of strings
|
396
|
+
# 2. is a subset of ["'script'"]
|
397
|
+
def validate_require_trusted_types_for_source_expression!(directive, require_trusted_types_for_expression)
|
398
|
+
ensure_array_of_strings!(directive, require_trusted_types_for_expression)
|
399
|
+
unless require_trusted_types_for_expression.to_set.subset?(REQUIRE_TRUSTED_TYPES_FOR_VALUES)
|
400
|
+
raise ContentSecurityPolicyConfigError.new(%(require-trusted-types-for for must be a subset of #{REQUIRE_TRUSTED_TYPES_FOR_VALUES.to_a} but was #{require_trusted_types_for_expression}))
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
371
404
|
# Private: validates that a source expression:
|
372
405
|
# 1. is an array of strings
|
373
406
|
# 2. does not contain any deprecated, now invalid values (inline, eval, self, none)
|
@@ -147,12 +147,13 @@ module SecureHeaders
|
|
147
147
|
|
148
148
|
def nonced_tag(type, content_or_options, block)
|
149
149
|
options = {}
|
150
|
-
content =
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
150
|
+
content =
|
151
|
+
if block
|
152
|
+
options = content_or_options
|
153
|
+
capture(&block)
|
154
|
+
else
|
155
|
+
content_or_options.html_safe # :'(
|
156
|
+
end
|
156
157
|
content_tag type, content, options.merge(nonce: _content_security_policy_nonce(type))
|
157
158
|
end
|
158
159
|
|
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
|
@@ -101,8 +101,13 @@ module SecureHeaders
|
|
101
101
|
expect(csp.value).to eq("default-src example.org; block-all-mixed-content")
|
102
102
|
end
|
103
103
|
|
104
|
-
it "
|
105
|
-
csp = ContentSecurityPolicy.new(default_src: %w(example.org
|
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:*")
|
107
|
+
end
|
108
|
+
|
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
|
|
@@ -146,6 +151,11 @@ module SecureHeaders
|
|
146
151
|
expect(csp.value).to eq("default-src 'self'; require-sri-for script style")
|
147
152
|
end
|
148
153
|
|
154
|
+
it "allows style as a require-trusted-types-for source" do
|
155
|
+
csp = ContentSecurityPolicy.new(default_src: %w('self'), require_trusted_types_for: %w(script))
|
156
|
+
expect(csp.value).to eq("default-src 'self'; require-trusted-types-for script")
|
157
|
+
end
|
158
|
+
|
149
159
|
it "includes prefetch-src" do
|
150
160
|
csp = ContentSecurityPolicy.new(default_src: %w('self'), prefetch_src: %w(foo.com))
|
151
161
|
expect(csp.value).to eq("default-src 'self'; prefetch-src foo.com")
|
@@ -185,6 +195,21 @@ module SecureHeaders
|
|
185
195
|
csp = ContentSecurityPolicy.new({style_src: %w('self'), style_src_attr: %w('self')})
|
186
196
|
expect(csp.value).to eq("style-src 'self'; style-src-attr 'self'")
|
187
197
|
end
|
198
|
+
|
199
|
+
it "supports trusted-types directive" do
|
200
|
+
csp = ContentSecurityPolicy.new({trusted_types: %w(blahblahpolicy)})
|
201
|
+
expect(csp.value).to eq("trusted-types blahblahpolicy")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "supports trusted-types directive with 'none'" do
|
205
|
+
csp = ContentSecurityPolicy.new({trusted_types: %w('none')})
|
206
|
+
expect(csp.value).to eq("trusted-types 'none'")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "allows duplicate policy names in trusted-types directive" do
|
210
|
+
csp = ContentSecurityPolicy.new({trusted_types: %w(blahblahpolicy 'allow-duplicates')})
|
211
|
+
expect(csp.value).to eq("trusted-types blahblahpolicy 'allow-duplicates'")
|
212
|
+
end
|
188
213
|
end
|
189
214
|
end
|
190
215
|
end
|
@@ -45,6 +45,7 @@ module SecureHeaders
|
|
45
45
|
plugin_types: %w(application/x-shockwave-flash),
|
46
46
|
prefetch_src: %w(fetch.com),
|
47
47
|
require_sri_for: %w(script style),
|
48
|
+
require_trusted_types_for: %w('script'),
|
48
49
|
script_src: %w('self'),
|
49
50
|
style_src: %w('unsafe-inline'),
|
50
51
|
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
|
@@ -53,6 +54,7 @@ module SecureHeaders
|
|
53
54
|
script_src_attr: %w(example.com),
|
54
55
|
style_src_elem: %w(example.com),
|
55
56
|
style_src_attr: %w(example.com),
|
57
|
+
trusted_types: %w(abcpolicy),
|
56
58
|
|
57
59
|
report_uri: %w(https://example.com/uri-directive),
|
58
60
|
}
|
@@ -120,6 +122,12 @@ module SecureHeaders
|
|
120
122
|
end.to raise_error(ContentSecurityPolicyConfigError)
|
121
123
|
end
|
122
124
|
|
125
|
+
it "rejects style for trusted types" do
|
126
|
+
expect do
|
127
|
+
ContentSecurityPolicy.validate_config!(ContentSecurityPolicyConfig.new(default_opts.merge(style_src: %w('self'), require_trusted_types_for: %w(script style), trusted_types: %w(abcpolicy))))
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
123
131
|
# this is mostly to ensure people don't use the antiquated shorthands common in other configs
|
124
132
|
it "performs light validation on source lists" do
|
125
133
|
expect do
|
@@ -6,7 +6,7 @@ class Message < ERB
|
|
6
6
|
include SecureHeaders::ViewHelpers
|
7
7
|
|
8
8
|
def self.template
|
9
|
-
<<-TEMPLATE
|
9
|
+
<<-TEMPLATE
|
10
10
|
<% hashed_javascript_tag(raise_error_on_unrecognized_hash = true) do %>
|
11
11
|
console.log(1)
|
12
12
|
<% end %>
|
@@ -62,9 +62,10 @@ TEMPLATE
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def content_tag(type, content = nil, options = nil, &block)
|
65
|
-
content =
|
66
|
-
|
67
|
-
|
65
|
+
content =
|
66
|
+
if block_given?
|
67
|
+
capture(block)
|
68
|
+
end
|
68
69
|
|
69
70
|
if options.is_a?(Hash)
|
70
71
|
options = options.map { |k, v| " #{k}=#{v}" }
|
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.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Neil Matatall
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-25 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: []
|
@@ -99,9 +102,9 @@ files:
|
|
99
102
|
- spec/spec_helper.rb
|
100
103
|
homepage: https://github.com/twitter/secureheaders
|
101
104
|
licenses:
|
102
|
-
-
|
105
|
+
- MIT
|
103
106
|
metadata: {}
|
104
|
-
post_install_message:
|
107
|
+
post_install_message:
|
105
108
|
rdoc_options: []
|
106
109
|
require_paths:
|
107
110
|
- lib
|
@@ -116,11 +119,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
119
|
- !ruby/object:Gem::Version
|
117
120
|
version: '0'
|
118
121
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
120
|
-
signing_key:
|
122
|
+
rubygems_version: 3.3.7
|
123
|
+
signing_key:
|
121
124
|
specification_version: 4
|
122
|
-
summary:
|
123
|
-
x-frame-options, strict-transport-security, etc.
|
125
|
+
summary: Manages application of security headers with many safe defaults.
|
124
126
|
test_files:
|
125
127
|
- spec/lib/secure_headers/configuration_spec.rb
|
126
128
|
- spec/lib/secure_headers/headers/clear_site_data_spec.rb
|