secure_headers 3.5.0.pre → 3.5.0
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/.ruby-version +1 -1
- data/CHANGELOG.md +2 -1
- data/Gemfile +1 -0
- data/README.md +2 -7
- data/lib/secure_headers.rb +1 -0
- data/lib/secure_headers/configuration.rb +1 -1
- data/lib/secure_headers/headers/content_security_policy.rb +2 -1
- data/lib/secure_headers/headers/policy_management.rb +9 -0
- data/lib/secure_headers/view_helper.rb +8 -0
- data/secure_headers.gemspec +1 -1
- data/spec/lib/secure_headers/middleware_spec.rb +12 -0
- data/spec/lib/secure_headers/view_helpers_spec.rb +10 -0
- data/spec/lib/secure_headers_spec.rb +14 -0
- data/spec/spec_helper.rb +2 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f47871f10c97316165d3f4230ddae85935d9a736
|
4
|
+
data.tar.gz: f5777312e07643e054d48b4121ba30a905aab4dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8516799304bf21ea8d67aace99325df8c34d1e3d72082b44ad4a80c658ddc9cee6e4a04fc8202ac062044c0abbc91ce870fc26a472960f390fe359670f7362cf
|
7
|
+
data.tar.gz: d4fc7f5482fc8e904ce3ea80340da5c5426b87c88bbb8f669af9e050b212a1189b997de0c3c6bdc9a3b4df58c69efa54598ea40caaf56eb9bc69a80722029f8c
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.2.
|
1
|
+
2.2.5
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -20,10 +20,6 @@ It can also mark all http cookies with the Secure, HttpOnly and SameSite attribu
|
|
20
20
|
|
21
21
|
`secure_headers` is a library with a global config, per request overrides, and rack middleware that enables you customize your application settings.
|
22
22
|
|
23
|
-
## Use
|
24
|
-
|
25
|
-
`gem install secure_headers`
|
26
|
-
|
27
23
|
## Configuration
|
28
24
|
|
29
25
|
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.
|
@@ -48,7 +44,7 @@ SecureHeaders::Configuration.default do |config|
|
|
48
44
|
config.referrer_policy = "origin-when-cross-origin"
|
49
45
|
config.csp = {
|
50
46
|
# "meta" values. these will shaped the header, but the values are not included in the header.
|
51
|
-
report_only: true, # default: false [DEPRECATED: instead, configure csp_report_only]
|
47
|
+
report_only: true, # default: false [DEPRECATED from 3.5.0: instead, configure csp_report_only]
|
52
48
|
preserve_schemes: true, # default: false. Schemes are removed from host sources to save bytes and discourage mixed content.
|
53
49
|
|
54
50
|
# directive values: these values will directly translate into source directives
|
@@ -69,6 +65,7 @@ SecureHeaders::Configuration.default do |config|
|
|
69
65
|
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
|
70
66
|
report_uri: %w(https://report-uri.io/example-csp)
|
71
67
|
}
|
68
|
+
# This is available only from 3.5.0; use the `report_only: true` setting for 3.4.1 and below.
|
72
69
|
config.csp_report_only = config.csp.merge({
|
73
70
|
img_src: %w(somewhereelse.com),
|
74
71
|
report_uri: %w(https://report-uri.io/example-csp-report-only)
|
@@ -121,8 +118,6 @@ Configuration.default do |config|
|
|
121
118
|
end
|
122
119
|
```
|
123
120
|
|
124
|
-
If **
|
125
|
-
|
126
121
|
## Named Appends
|
127
122
|
|
128
123
|
Named Appends are blocks of code that can be reused and composed during requests. e.g. If a certain partial is rendered conditionally, and the csp needs to be adjusted for that partial, you can create a named append for that situation. The value returned by the block will be passed into `append_content_security_policy_directives`. The current request object is passed as an argument to the block for even more flexibility.
|
data/lib/secure_headers.rb
CHANGED
@@ -47,6 +47,7 @@ module SecureHeaders
|
|
47
47
|
SECURE_HEADERS_CONFIG = "secure_headers_request_config".freeze
|
48
48
|
NONCE_KEY = "secure_headers_content_security_policy_nonce".freeze
|
49
49
|
HTTPS = "https".freeze
|
50
|
+
CSP = ContentSecurityPolicy
|
50
51
|
|
51
52
|
ALL_HEADER_CLASSES = [
|
52
53
|
ContentSecurityPolicyConfig,
|
@@ -140,7 +140,7 @@ module SecureHeaders
|
|
140
140
|
# Returns a deep-dup'd copy of this configuration.
|
141
141
|
def dup
|
142
142
|
copy = self.class.new
|
143
|
-
copy.cookies = @cookies
|
143
|
+
copy.cookies = self.class.send(:deep_copy_if_hash, @cookies)
|
144
144
|
copy.csp = @csp.dup if @csp
|
145
145
|
copy.csp_report_only = @csp_report_only.dup if @csp_report_only
|
146
146
|
copy.cached_headers = self.class.send(:deep_copy_if_hash, @cached_headers)
|
@@ -8,6 +8,7 @@ module SecureHeaders
|
|
8
8
|
|
9
9
|
# constants to be used for version-specific UA sniffing
|
10
10
|
VERSION_46 = ::UserAgent::Version.new("46")
|
11
|
+
VERSION_10 = ::UserAgent::Version.new("10")
|
11
12
|
|
12
13
|
def initialize(config = nil, user_agent = OTHER)
|
13
14
|
@config = if config.is_a?(Hash)
|
@@ -223,7 +224,7 @@ module SecureHeaders
|
|
223
224
|
end
|
224
225
|
|
225
226
|
def nonces_supported?
|
226
|
-
@nonces_supported ||=
|
227
|
+
@nonces_supported ||= self.class.nonces_supported?(@parsed_ua)
|
227
228
|
end
|
228
229
|
|
229
230
|
def symbol_to_hyphen_case(sym)
|
@@ -211,6 +211,15 @@ module SecureHeaders
|
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
214
|
+
# Public: check if a user agent supports CSP nonces
|
215
|
+
#
|
216
|
+
# user_agent - a String or a UserAgent object
|
217
|
+
def nonces_supported?(user_agent)
|
218
|
+
user_agent = UserAgent.parse(user_agent) if user_agent.is_a?(String)
|
219
|
+
MODERN_BROWSERS.include?(user_agent.browser) ||
|
220
|
+
user_agent.browser == "Safari" && user_agent.version >= CSP::VERSION_10
|
221
|
+
end
|
222
|
+
|
214
223
|
# Public: combine the values from two different configs.
|
215
224
|
#
|
216
225
|
# original - the main config
|
@@ -34,6 +34,14 @@ module SecureHeaders
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
def content_security_policy_script_nonce
|
38
|
+
content_security_policy_nonce(:script)
|
39
|
+
end
|
40
|
+
|
41
|
+
def content_security_policy_style_nonce
|
42
|
+
content_security_policy_nonce(:style)
|
43
|
+
end
|
44
|
+
|
37
45
|
##
|
38
46
|
# Checks to see if the hashed code is expected and adds the hash source
|
39
47
|
# value to the current CSP.
|
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.5.0
|
4
|
+
gem.version = "3.5.0"
|
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.'
|
@@ -105,6 +105,18 @@ module SecureHeaders
|
|
105
105
|
_, env = cookie_middleware.call request.env
|
106
106
|
expect(env['Set-Cookie']).to eq("foo=bar")
|
107
107
|
end
|
108
|
+
|
109
|
+
it "sets the secure cookie flag correctly on interleaved http/https requests" do
|
110
|
+
Configuration.default { |config| config.cookies = { secure: true } }
|
111
|
+
|
112
|
+
request = Rack::Request.new("HTTPS" => "off")
|
113
|
+
_, env = cookie_middleware.call request.env
|
114
|
+
expect(env['Set-Cookie']).to eq("foo=bar")
|
115
|
+
|
116
|
+
request = Rack::Request.new("HTTPS" => "on")
|
117
|
+
_, env = cookie_middleware.call request.env
|
118
|
+
expect(env['Set-Cookie']).to eq("foo=bar; secure")
|
119
|
+
end
|
108
120
|
end
|
109
121
|
end
|
110
122
|
end
|
@@ -27,6 +27,16 @@ class Message < ERB
|
|
27
27
|
background-color: black;
|
28
28
|
}
|
29
29
|
<% end %>
|
30
|
+
|
31
|
+
<script nonce="<%= content_security_policy_script_nonce %>">
|
32
|
+
alert(1)
|
33
|
+
</script>
|
34
|
+
|
35
|
+
<style nonce="<%= content_security_policy_style_nonce %>">
|
36
|
+
body {
|
37
|
+
background-color: black;
|
38
|
+
}
|
39
|
+
</style>
|
30
40
|
<%= @name %>
|
31
41
|
|
32
42
|
TEMPLATE
|
@@ -277,6 +277,20 @@ module SecureHeaders
|
|
277
277
|
expect(hash['Content-Security-Policy']).to eq("default-src 'self'; script-src mycdn.com 'nonce-#{nonce}'; style-src 'self'")
|
278
278
|
end
|
279
279
|
|
280
|
+
it "uses a nonce for safari 10+" do
|
281
|
+
Configuration.default do |config|
|
282
|
+
config.csp = {
|
283
|
+
default_src: %w('self'),
|
284
|
+
script_src: %w(mycdn.com)
|
285
|
+
}
|
286
|
+
end
|
287
|
+
|
288
|
+
safari_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:safari10]))
|
289
|
+
nonce = SecureHeaders.content_security_policy_script_nonce(safari_request)
|
290
|
+
hash = SecureHeaders.header_hash_for(safari_request)
|
291
|
+
expect(hash['Content-Security-Policy']).to eq("default-src 'self'; script-src mycdn.com 'nonce-#{nonce}'")
|
292
|
+
end
|
293
|
+
|
280
294
|
it "supports the deprecated `report_only: true` format" do
|
281
295
|
expect(Kernel).to receive(:warn).once
|
282
296
|
|
data/spec/spec_helper.rb
CHANGED
@@ -21,7 +21,8 @@ USER_AGENTS = {
|
|
21
21
|
ios6: "Mozilla/5.0 (iPhone; CPU iPhone OS 614 like Mac OS X) AppleWebKit/536.26 (KHTML like Gecko) Version/6.0 Mobile/10B350 Safari/8536.25",
|
22
22
|
safari5: "Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3",
|
23
23
|
safari5_1: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10",
|
24
|
-
safari6: "Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1"
|
24
|
+
safari6: "Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1",
|
25
|
+
safari10: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.11 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.11"
|
25
26
|
}
|
26
27
|
|
27
28
|
def expect_default_values(hash)
|
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.5.0
|
4
|
+
version: 3.5.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: 2016-
|
11
|
+
date: 2016-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -111,9 +111,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
111
|
version: '0'
|
112
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
|
-
- - "
|
114
|
+
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
116
|
+
version: '0'
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
119
|
rubygems_version: 2.4.5.1
|