secure_headers 3.5.0.pre → 3.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.
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
|