secure_headers 3.0.0.pre2 → 3.0.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of secure_headers might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +27 -23
- data/lib/secure_headers.rb +14 -8
- data/lib/secure_headers/headers/content_security_policy.rb +27 -13
- data/secure_headers.gemspec +1 -1
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +53 -0
- data/upgrading-to-3-0.md +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e0a5f8e1d4955125f71ede3b2f1bd882ccaca56
|
4
|
+
data.tar.gz: 656cc8d6965a49288b7ccd2ab3fc91fb13ab9792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a61ccca281e3968c41aa6daf1d069b6a6aef9d796c62cc0b5c7be45007fc3ca41908f71310c289c854e386dfafbb1b96cfa5eca45fc598f43113edb8b7678f0
|
7
|
+
data.tar.gz: edd0190e206824a91e961131f8f612ac7a10559ced00c9b314cba681d579cfc27c9280205dbe687725579a7a242fcae70c6e4a279bafcb2981e63ee00679c4e6
|
data/README.md
CHANGED
@@ -1,26 +1,31 @@
|
|
1
|
-
#
|
1
|
+
# Secure Headers [![Build Status](https://travis-ci.org/twitter/secureheaders.png?branch=master)](http://travis-ci.org/twitter/secureheaders) [![Code Climate](https://codeclimate.com/github/twitter/secureheaders.png)](https://codeclimate.com/github/twitter/secureheaders) [![Coverage Status](https://coveralls.io/repos/twitter/secureheaders/badge.png)](https://coveralls.io/r/twitter/secureheaders)
|
2
|
+
|
2
3
|
|
3
4
|
**The 3.x branch was recently merged**. See the [upgrading to 3.x doc](upgrading-to-3-0.md) for instructions on how to upgrade including the differences and benefits of using the 3.x branch.
|
4
5
|
|
5
|
-
**The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be maintained**. The documentation below only applies to the
|
6
|
+
**The [2.x branch](https://github.com/twitter/secureheaders/tree/2.x) will be maintained**. The documentation below only applies to the 3.x branch. See the 2.x [README](https://github.com/twitter/secureheaders/blob/2.x/README.md) for the old way of doing things.
|
6
7
|
|
7
8
|
The gem will automatically apply several headers that are related to security. This includes:
|
8
9
|
- Content Security Policy (CSP) - Helps detect/prevent XSS, mixed-content, and other classes of attack. [CSP 2 Specification](http://www.w3.org/TR/CSP2/)
|
9
10
|
- HTTP Strict Transport Security (HSTS) - Ensures the browser never visits the http version of a website. Protects from SSLStrip/Firesheep attacks. [HSTS Specification](https://tools.ietf.org/html/rfc6797)
|
10
11
|
- X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options draft](https://tools.ietf.org/html/draft-ietf-websec-x-frame-options-02)
|
11
|
-
- X-XSS-Protection - [Cross site scripting heuristic filter for IE/Chrome](
|
12
|
-
- X-Content-Type-Options - [Prevent content type sniffing](
|
13
|
-
- X-Download-Options - [Prevent file downloads opening](
|
12
|
+
- X-XSS-Protection - [Cross site scripting heuristic filter for IE/Chrome](https://msdn.microsoft.com/en-us/library/dd565647\(v=vs.85\).aspx)
|
13
|
+
- X-Content-Type-Options - [Prevent content type sniffing](https://msdn.microsoft.com/library/gg622941\(v=vs.85\).aspx)
|
14
|
+
- X-Download-Options - [Prevent file downloads opening](https://msdn.microsoft.com/library/jj542450(v=vs.85).aspx)
|
14
15
|
- 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)
|
15
16
|
- 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)
|
16
17
|
|
17
|
-
`secure_headers` is a library with a global config, per request overrides, and rack
|
18
|
+
`secure_headers` is a library with a global config, per request overrides, and rack middleware that enables you customize your application settings.
|
19
|
+
|
20
|
+
## Use
|
21
|
+
|
22
|
+
`gem install secure_headers`
|
18
23
|
|
19
24
|
## Configuration
|
20
25
|
|
21
26
|
If you do not supply a `default` configuration, exceptions will be raised. If you would like to use a default configuration (which is fairly locked down), just call `SecureHeaders::Configuration.default` without any arguments or block.
|
22
27
|
|
23
|
-
All `nil` values will fallback to their default
|
28
|
+
All `nil` values will fallback to their default values. `SecureHeaders::OPT_OUT` will disable the header entirely.
|
24
29
|
|
25
30
|
```ruby
|
26
31
|
SecureHeaders::Configuration.default do |config|
|
@@ -31,12 +36,15 @@ SecureHeaders::Configuration.default do |config|
|
|
31
36
|
config.x_download_options = "noopen"
|
32
37
|
config.x_permitted_cross_domain_policies = "none"
|
33
38
|
config.csp = {
|
39
|
+
# "meta" values. these will shaped the header, but the values are not included in the header.
|
40
|
+
report_only: true, # default: false
|
41
|
+
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
|
42
|
+
|
43
|
+
# directive values: these values will directly translate into source directives
|
34
44
|
default_src: %w(https: 'self'),
|
35
|
-
|
36
|
-
frame_src: %w(*.twimg.com itunes.apple.com),
|
45
|
+
frame_src: %w('self' *.twimg.com itunes.apple.com),
|
37
46
|
connect_src: %w(wws:),
|
38
47
|
font_src: %w('self' data:),
|
39
|
-
frame_src: %w('self'),
|
40
48
|
img_src: %w(mycdn.com data:),
|
41
49
|
media_src: %w(utoob.com),
|
42
50
|
object_src: %w('self'),
|
@@ -129,7 +137,7 @@ end
|
|
129
137
|
|
130
138
|
## Per-action configuration
|
131
139
|
|
132
|
-
You can override the settings for a given action by producing a temporary override.
|
140
|
+
You can override the settings for a given action by producing a temporary override. Be aware that because of the dynamic nature of the value, the header values will be computed per request.
|
133
141
|
|
134
142
|
```ruby
|
135
143
|
# Given a config of:
|
@@ -148,7 +156,7 @@ class MyController < ApplicationController
|
|
148
156
|
|
149
157
|
# Overrides the previously set source list, override 'none' values
|
150
158
|
# Produces: default-src 'self'; script-src s3.amazaonaws.com; object-src 'self'
|
151
|
-
|
159
|
+
override_content_security_policy_directives(script_src: %w(s3.amazaonaws.com), object_src: %w('self'))
|
152
160
|
|
153
161
|
# Global settings default to "sameorigin"
|
154
162
|
override_x_frame_options("DENY")
|
@@ -157,7 +165,7 @@ class MyController < ApplicationController
|
|
157
165
|
|
158
166
|
The following methods are available as controller instance methods. They are also available as class methods, but require you to pass in the `request` object.
|
159
167
|
* `append_content_security_policy_directives(hash)`: appends each value to the corresponding CSP app-wide configuration.
|
160
|
-
* `
|
168
|
+
* `override_content_security_policy_directives(hash)`: merges the hash into the app-wide configuration, overwriting any previous config
|
161
169
|
* `override_x_frame_options(value)`: sets the `X-Frame-Options header` to `value`
|
162
170
|
|
163
171
|
## Appending / overriding Content Security Policy
|
@@ -169,7 +177,7 @@ When manipulating content security policy, there are a few things to consider. T
|
|
169
177
|
The value of `default_src` is joined with the addition. Note the `https:` is carried over from the `default-src` config. If you do not want this, use `override_content_security_policy_directives` instead. To illustrate:
|
170
178
|
|
171
179
|
```ruby
|
172
|
-
::SecureHeaders::Configuration.
|
180
|
+
::SecureHeaders::Configuration.default do |config|
|
173
181
|
config.csp = {
|
174
182
|
default_src: %w('self')
|
175
183
|
}
|
@@ -181,11 +189,6 @@ Code | Result
|
|
181
189
|
`append_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src 'self'; script-src 'self' mycdn.com`
|
182
190
|
`override_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src 'self'; script-src mycdn.com`
|
183
191
|
|
184
|
-
Code | Result
|
185
|
-
------------- | -------------
|
186
|
-
`append_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src https:; script-src https: mycdn.com`
|
187
|
-
`override_content_security_policy_directives(script_src: %w(mycdn.com))` | `default-src https:; script-src mycdn.com`
|
188
|
-
|
189
192
|
#### Nonce
|
190
193
|
|
191
194
|
script/style-nonce can be used to whitelist inline content. To do this, call the SecureHeaders::content_security_policy_nonce then set the nonce attributes on the various tags.
|
@@ -269,7 +272,7 @@ require 'secure_headers'
|
|
269
272
|
|
270
273
|
use SecureHeaders::Middleware
|
271
274
|
|
272
|
-
SecureHeaders::Configuration.
|
275
|
+
SecureHeaders::Configuration.default do |config|
|
273
276
|
...
|
274
277
|
end
|
275
278
|
|
@@ -314,7 +317,7 @@ and in `config/boot.rb`:
|
|
314
317
|
|
315
318
|
```ruby
|
316
319
|
def before_load
|
317
|
-
SecureHeaders::Configuration.
|
320
|
+
SecureHeaders::Configuration.default do |config|
|
318
321
|
...
|
319
322
|
end
|
320
323
|
end
|
@@ -322,13 +325,14 @@ end
|
|
322
325
|
|
323
326
|
## Similar libraries
|
324
327
|
|
325
|
-
* Rack [rack-secure_headers](https://github.com/
|
326
|
-
* Node.js (express) [helmet](https://github.com/
|
328
|
+
* Rack [rack-secure_headers](https://github.com/frodsan/rack-secure_headers)
|
329
|
+
* Node.js (express) [helmet](https://github.com/helmetjs/helmet) and [hood](https://github.com/seanmonstar/hood)
|
327
330
|
* Node.js (hapi) [blankie](https://github.com/nlf/blankie)
|
328
331
|
* J2EE Servlet >= 3.0 [headlines](https://github.com/sourceclear/headlines)
|
329
332
|
* ASP.NET - [NWebsec](https://github.com/NWebsec/NWebsec/wiki)
|
330
333
|
* Python - [django-csp](https://github.com/mozilla/django-csp) + [commonware](https://github.com/jsocol/commonware/); [django-security](https://github.com/sdelements/django-security)
|
331
334
|
* Go - [secureheader](https://github.com/kr/secureheader)
|
335
|
+
* Elixir [secure_headers](https://github.com/anotherhale/secure_headers)
|
332
336
|
|
333
337
|
## License
|
334
338
|
|
data/lib/secure_headers.rb
CHANGED
@@ -47,12 +47,15 @@ module SecureHeaders
|
|
47
47
|
# additions - a hash containing directives. e.g.
|
48
48
|
# script_src: %w(another-host.com)
|
49
49
|
def override_content_security_policy_directives(request, additions)
|
50
|
-
config = config_for(request)
|
51
|
-
|
52
|
-
config
|
50
|
+
config = config_for(request)
|
51
|
+
unless CSP.idempotent_additions?(config.csp, additions)
|
52
|
+
config = config.dup
|
53
|
+
if config.csp == OPT_OUT
|
54
|
+
config.csp = {}
|
55
|
+
end
|
56
|
+
config.csp.merge!(additions)
|
57
|
+
override_secure_headers_request_config(request, config)
|
53
58
|
end
|
54
|
-
config.csp.merge!(additions)
|
55
|
-
override_secure_headers_request_config(request, config)
|
56
59
|
end
|
57
60
|
|
58
61
|
# Public: appends source values to the current configuration. If no value
|
@@ -62,9 +65,12 @@ module SecureHeaders
|
|
62
65
|
# additions - a hash containing directives. e.g.
|
63
66
|
# script_src: %w(another-host.com)
|
64
67
|
def append_content_security_policy_directives(request, additions)
|
65
|
-
config = config_for(request)
|
66
|
-
|
67
|
-
|
68
|
+
config = config_for(request)
|
69
|
+
unless CSP.idempotent_additions?(config.csp, additions)
|
70
|
+
config = config.dup
|
71
|
+
config.csp = CSP.combine_policies(config.csp, additions)
|
72
|
+
override_secure_headers_request_config(request, config)
|
73
|
+
end
|
68
74
|
end
|
69
75
|
|
70
76
|
# Public: override X-Frame-Options settings for this request.
|
@@ -145,7 +145,12 @@ module SecureHeaders
|
|
145
145
|
STAR,
|
146
146
|
DATA_PROTOCOL,
|
147
147
|
BLOB_PROTOCOL
|
148
|
-
]
|
148
|
+
].freeze
|
149
|
+
|
150
|
+
META_CONFIGS = [
|
151
|
+
:report_only,
|
152
|
+
:preserve_schemes
|
153
|
+
].freeze
|
149
154
|
|
150
155
|
class << self
|
151
156
|
# Public: generate a header name, value array that is user-agent-aware.
|
@@ -157,13 +162,7 @@ module SecureHeaders
|
|
157
162
|
[header.name, header.value]
|
158
163
|
end
|
159
164
|
|
160
|
-
# Public: Validates
|
161
|
-
# source expression.
|
162
|
-
#
|
163
|
-
# Private: validates that a source expression:
|
164
|
-
# 1. has a valid name
|
165
|
-
# 2. is an array of strings
|
166
|
-
# 3. does not contain any depreated, now invalid values (inline, eval, self, none)
|
165
|
+
# Public: Validates each source expression.
|
167
166
|
#
|
168
167
|
# Does not validate the invididual values of the source expression (e.g.
|
169
168
|
# script_src => h*t*t*p: will not raise an exception)
|
@@ -171,7 +170,7 @@ module SecureHeaders
|
|
171
170
|
return if config.nil? || config == OPT_OUT
|
172
171
|
raise ContentSecurityPolicyConfigError.new(":default_src is required") unless config[:default_src]
|
173
172
|
config.each do |key, value|
|
174
|
-
if key
|
173
|
+
if META_CONFIGS.include?(key)
|
175
174
|
raise ContentSecurityPolicyConfigError.new("#{key} must be a boolean value") unless boolean?(value) || value.nil?
|
176
175
|
else
|
177
176
|
validate_directive!(key, value)
|
@@ -179,6 +178,17 @@ module SecureHeaders
|
|
179
178
|
end
|
180
179
|
end
|
181
180
|
|
181
|
+
# Public: determine if merging +additions+ will cause a change to the
|
182
|
+
# actual value of the config.
|
183
|
+
#
|
184
|
+
# e.g. config = { script_src: %w(example.org google.com)} and
|
185
|
+
# additions = { script_src: %w(google.com)} then idempotent_additions? would return
|
186
|
+
# because google.com is already in the config.
|
187
|
+
def idempotent_additions?(config, additions)
|
188
|
+
return false if config == OPT_OUT
|
189
|
+
config.to_s == combine_policies(config, additions).to_s
|
190
|
+
end
|
191
|
+
|
182
192
|
# Public: combine the values from two different configs.
|
183
193
|
#
|
184
194
|
# original - the main config
|
@@ -208,11 +218,11 @@ module SecureHeaders
|
|
208
218
|
# when each hash contains a value for a given key.
|
209
219
|
original.merge(additions) do |directive, lhs, rhs|
|
210
220
|
if source_list?(directive)
|
211
|
-
lhs
|
221
|
+
(lhs.to_a + rhs).uniq.compact
|
212
222
|
else
|
213
223
|
rhs
|
214
224
|
end
|
215
|
-
end
|
225
|
+
end.reject { |_, value| value.nil? || value == [] } # this mess prevents us from adding empty directives.
|
216
226
|
end
|
217
227
|
|
218
228
|
private
|
@@ -275,7 +285,8 @@ module SecureHeaders
|
|
275
285
|
else
|
276
286
|
UserAgent.parse(user_agent)
|
277
287
|
end
|
278
|
-
@report_only =
|
288
|
+
@report_only = @config[:report_only]
|
289
|
+
@preserve_schemes = @config[:preserve_schemes]
|
279
290
|
@script_nonce = @config[:script_nonce]
|
280
291
|
@style_nonce = @config[:style_nonce]
|
281
292
|
end
|
@@ -345,9 +356,12 @@ module SecureHeaders
|
|
345
356
|
source_list.reject! { |value| value == NONE } if source_list.length > 1
|
346
357
|
|
347
358
|
# remove schemes and dedup source expressions
|
348
|
-
|
359
|
+
unless directive_name == REPORT_URI || @preserve_schemes
|
360
|
+
source_list = strip_source_schemes(source_list)
|
361
|
+
end
|
349
362
|
dedup_source_list(source_list).join(" ")
|
350
363
|
end
|
364
|
+
|
351
365
|
[symbol_to_hyphen_case(directive_name), value].join(" ")
|
352
366
|
end
|
353
367
|
|
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.0.0.
|
4
|
+
gem.version = "3.0.0.pre3"
|
5
5
|
gem.authors = ["Neil Matatall"]
|
6
6
|
gem.email = ["neil.matatall@gmail.com"]
|
7
7
|
gem.description = 'Security related headers all in one gem.'
|
@@ -23,6 +23,35 @@ module SecureHeaders
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe "#validate_config!" do
|
26
|
+
it "accepts all keys" do
|
27
|
+
# (pulled from README)
|
28
|
+
config = {
|
29
|
+
# "meta" values. these will shaped the header, but the values are not included in the header.
|
30
|
+
report_only: true, # default: false
|
31
|
+
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
|
32
|
+
|
33
|
+
# directive values: these values will directly translate into source directives
|
34
|
+
default_src: %w(https: 'self'),
|
35
|
+
frame_src: %w('self' *.twimg.com itunes.apple.com),
|
36
|
+
connect_src: %w(wws:),
|
37
|
+
font_src: %w('self' data:),
|
38
|
+
img_src: %w(mycdn.com data:),
|
39
|
+
media_src: %w(utoob.com),
|
40
|
+
object_src: %w('self'),
|
41
|
+
script_src: %w('self'),
|
42
|
+
style_src: %w('unsafe-inline'),
|
43
|
+
base_uri: %w('self'),
|
44
|
+
child_src: %w('self'),
|
45
|
+
form_action: %w('self' github.com),
|
46
|
+
frame_ancestors: %w('none'),
|
47
|
+
plugin_types: %w(application/x-shockwave-flash),
|
48
|
+
block_all_mixed_content: true, # see [http://www.w3.org/TR/mixed-content/](http://www.w3.org/TR/mixed-content/)
|
49
|
+
report_uri: %w(https://example.com/uri-directive)
|
50
|
+
}
|
51
|
+
|
52
|
+
CSP.validate_config!(config)
|
53
|
+
end
|
54
|
+
|
26
55
|
it "requires a :default_src value" do
|
27
56
|
expect do
|
28
57
|
CSP.validate_config!(script_src: %('self'))
|
@@ -35,6 +64,12 @@ module SecureHeaders
|
|
35
64
|
end.to raise_error(ContentSecurityPolicyConfigError)
|
36
65
|
end
|
37
66
|
|
67
|
+
it "requires :preserve_schemes to be a truthy value" do
|
68
|
+
expect do
|
69
|
+
CSP.validate_config!(default_opts.merge(preserve_schemes: "steve"))
|
70
|
+
end.to raise_error(ContentSecurityPolicyConfigError)
|
71
|
+
end
|
72
|
+
|
38
73
|
it "requires :block_all_mixed_content to be a boolean value" do
|
39
74
|
expect do
|
40
75
|
CSP.validate_config!(default_opts.merge(block_all_mixed_content: "steve"))
|
@@ -109,6 +144,19 @@ module SecureHeaders
|
|
109
144
|
end
|
110
145
|
end
|
111
146
|
|
147
|
+
describe "#idempotent_additions?" do
|
148
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?(OPT_OUT, script_src: %w(b.com))).to be false }
|
149
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: %w(c.com))).to be false }
|
150
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, style_src: %w(b.com))).to be false }
|
151
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: %w(a.com b.com c.com))).to be false }
|
152
|
+
|
153
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: %w(b.com))).to be true }
|
154
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: %w(b.com a.com))).to be true }
|
155
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: %w())).to be true }
|
156
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, script_src: [nil])).to be true }
|
157
|
+
specify { expect(ContentSecurityPolicy.idempotent_additions?({script_src: %w(a.com b.com)}, style_src: [nil])).to be true }
|
158
|
+
end
|
159
|
+
|
112
160
|
describe "#value" do
|
113
161
|
it "discards 'none' values if any other source expressions are present" do
|
114
162
|
csp = ContentSecurityPolicy.new(default_opts.merge(frame_src: %w('self' 'none')))
|
@@ -138,6 +186,11 @@ module SecureHeaders
|
|
138
186
|
expect(csp.value).to eq("default-src https:; report-uri https://example.org")
|
139
187
|
end
|
140
188
|
|
189
|
+
it "does not remove schemes when :preserve_schemes is true" do
|
190
|
+
csp = ContentSecurityPolicy.new(default_src: %w(https://example.org), :preserve_schemes => true)
|
191
|
+
expect(csp.value).to eq("default-src https://example.org")
|
192
|
+
end
|
193
|
+
|
141
194
|
it "removes nil from source lists" do
|
142
195
|
csp = ContentSecurityPolicy.new(default_src: ["https://example.org", nil])
|
143
196
|
expect(csp.value).to eq("default-src example.org")
|
data/upgrading-to-3-0.md
CHANGED
@@ -11,6 +11,7 @@ Changes
|
|
11
11
|
| `self`/`none` source expressions | could be `self` / `none` / `'self'` / `'none'` | Must be `'self'` or `'none'` |
|
12
12
|
| `inline` / `eval` source expressions | could be `inline`, `eval`, `'unsafe-inline'`, or `'unsafe-eval'` | Must be `'unsafe-eval'` or `'unsafe-inline'` |
|
13
13
|
| Per-action configuration | override [`def secure_header_options_for(header, options)`](https://github.com/twitter/secureheaders/commit/bb9ebc6c12a677aad29af8e0f08ffd1def56efec#diff-04c6e90faac2675aa89e2176d2eec7d8R111) | Use [named overrides](https://github.com/twitter/secureheaders#named-overrides) or [per-action helpers](https://github.com/twitter/secureheaders#per-action-configuration) |
|
14
|
+
| CSP/HPKP use `report_only` config that defaults to false | `enforce: false` | `report_only: false` |
|
14
15
|
|
15
16
|
Migrating to 3.x from <= 2.x
|
16
17
|
==
|
@@ -18,6 +19,7 @@ Migrating to 3.x from <= 2.x
|
|
18
19
|
1. Convert all headers except for CSP/HPKP using hashes to string values. The values are validated at runtime and will provide guidance on misconfigured headers.
|
19
20
|
1. Convert all instances of `self`/`none`/`eval`/`inline` to the corresponding values in the above table.
|
20
21
|
1. Convert all CSP space-delimited directives to an array of strings.
|
22
|
+
1. Convert all `enforce: true|false` to `report_only: true|false`.
|
21
23
|
|
22
24
|
Everything is terrible, why should I upgrade?
|
23
25
|
==
|
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.0.0.
|
4
|
+
version: 3.0.0.pre3
|
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: 2016-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|