secure_headers 3.3.2 → 3.4.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/.github/ISSUE_TEMPLATE.md +41 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +2 -1
- data/README.md +8 -9
- data/lib/secure_headers/configuration.rb +2 -2
- data/lib/secure_headers/headers/content_security_policy.rb +33 -3
- data/lib/secure_headers/headers/policy_management.rb +14 -0
- data/lib/secure_headers/view_helper.rb +3 -5
- data/secure_headers.gemspec +1 -1
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +37 -11
- data/spec/lib/secure_headers/headers/policy_management_spec.rb +2 -2
- data/spec/lib/secure_headers_spec.rb +3 -2
- data/spec/spec_helper.rb +2 -1
- data/upgrading-to-3-0.md +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88233251c7a26e1269f77957d56823619e3d9d11
|
4
|
+
data.tar.gz: 8e9c0e69fcca0298ee52223d587134f5a8df062f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f421d0d58eb9b5a7b22fd13932644c2c3868e0294886cbf5250127e8807fa20dec95717219e0a82ce59f49f376b32e17b97b77c7e011d2e2d1633162c1297bbc
|
7
|
+
data.tar.gz: ae63cbdd588bf6c31e531bfec5480e022a5df96c8ee2cc4c824d1e869f64df2a44073d795cc6d5e7ffeca6d6369f0d2e33f202ce8ceda04d274849e95789ff43
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Feature Requests
|
2
|
+
|
3
|
+
## Adding a new header
|
4
|
+
|
5
|
+
Generally, adding a new header is always OK.
|
6
|
+
|
7
|
+
* Is the header supported by any user agent? If so, which?
|
8
|
+
* What does it do?
|
9
|
+
* What are the valid values for the header?
|
10
|
+
* Where does the specification live?
|
11
|
+
|
12
|
+
## Adding a new CSP directive
|
13
|
+
|
14
|
+
* Is the directive supported by any user agent? If so, which?
|
15
|
+
* What does it do?
|
16
|
+
* What are the valid values for the directive?
|
17
|
+
|
18
|
+
---
|
19
|
+
|
20
|
+
# Bugs
|
21
|
+
|
22
|
+
Console errors and deprecation warnings are considered bugs that should be addressed with more precise UA sniffing. Bugs caused by incorrect or invalid UA sniffing are also bugs.
|
23
|
+
|
24
|
+
### Expected outcome
|
25
|
+
|
26
|
+
Describe what you expected to happen
|
27
|
+
|
28
|
+
1. I configure CSP to do X
|
29
|
+
1. When I inspect the response headers, the CSP should have included X
|
30
|
+
|
31
|
+
### Actual outcome
|
32
|
+
|
33
|
+
1. The generated policy did not include X
|
34
|
+
|
35
|
+
### Config
|
36
|
+
|
37
|
+
Please provide the configuration (`SecureHeaders::Configuration.default`) you are using including any overrides (`SecureHeaders::Configuration.override`).
|
38
|
+
|
39
|
+
### Generated headers
|
40
|
+
|
41
|
+
Provide a sample response containing the headers
|
@@ -0,0 +1,20 @@
|
|
1
|
+
## All PRs:
|
2
|
+
|
3
|
+
* [ ] Has tests
|
4
|
+
* [ ] Documentation updated
|
5
|
+
|
6
|
+
## Adding a new header
|
7
|
+
|
8
|
+
Generally, adding a new header is always OK.
|
9
|
+
|
10
|
+
* Is the header supported by any user agent? If so, which?
|
11
|
+
* What does it do?
|
12
|
+
* What are the valid values for the header?
|
13
|
+
* Where does the specification live?
|
14
|
+
|
15
|
+
## Adding a new CSP directive
|
16
|
+
|
17
|
+
* Is the directive supported by any user agent? If so, which?
|
18
|
+
* What does it do?
|
19
|
+
* What are the valid values for the directive?
|
20
|
+
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## 3.4.0 the frame-src/child-src transition for Firefox.
|
2
|
+
|
3
|
+
Handle the `child-src`/`frame-src` transition semi-intelligently across versions. I think the code best descibes the behavior here:
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
if supported_directives.include?(:child_src)
|
7
|
+
@config[:child_src] = @config[:child_src] || @config[:frame_src]
|
8
|
+
else
|
9
|
+
@config[:frame_src] = @config[:frame_src] || @config[:child_src]
|
10
|
+
end
|
11
|
+
```
|
12
|
+
|
13
|
+
Also, @koenpunt noticed that we were [loading view helpers](https://github.com/twitter/secureheaders/pull/272) in a way that Rails 5 did not like.
|
14
|
+
|
1
15
|
## 3.3.2 minor fix to silence warnings when using rake
|
2
16
|
|
3
17
|
[@dankohn](https://github.com/twitter/secureheaders/issues/257) was seeing "already initialized" errors in his output. This change conditionally defines the constants.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
The gem will automatically apply several headers that are related to security. This includes:
|
9
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/)
|
10
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)
|
11
|
-
- X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options
|
11
|
+
- X-Frame-Options (XFO) - Prevents your content from being framed and potentially clickjacked. [X-Frame-Options Specification](https://tools.ietf.org/html/rfc7034)
|
12
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
13
|
- X-Content-Type-Options - [Prevent content type sniffing](https://msdn.microsoft.com/library/gg622941\(v=vs.85\).aspx)
|
14
14
|
- X-Download-Options - [Prevent file downloads opening](https://msdn.microsoft.com/library/jj542450(v=vs.85).aspx)
|
@@ -53,20 +53,19 @@ SecureHeaders::Configuration.default do |config|
|
|
53
53
|
|
54
54
|
# directive values: these values will directly translate into source directives
|
55
55
|
default_src: %w(https: 'self'),
|
56
|
-
|
57
|
-
|
56
|
+
base_uri: %w('self'),
|
57
|
+
block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
|
58
|
+
child_src: %w('self'), # if child-src isn't supported, the value for frame-src will be set.
|
59
|
+
connect_src: %w(wss:),
|
58
60
|
font_src: %w('self' data:),
|
61
|
+
form_action: %w('self' github.com),
|
62
|
+
frame_ancestors: %w('none'),
|
59
63
|
img_src: %w(mycdn.com data:),
|
60
64
|
media_src: %w(utoob.com),
|
61
65
|
object_src: %w('self'),
|
66
|
+
plugin_types: %w(application/x-shockwave-flash),
|
62
67
|
script_src: %w('self'),
|
63
68
|
style_src: %w('unsafe-inline'),
|
64
|
-
base_uri: %w('self'),
|
65
|
-
child_src: %w('self'),
|
66
|
-
form_action: %w('self' github.com),
|
67
|
-
frame_ancestors: %w('none'),
|
68
|
-
plugin_types: %w(application/x-shockwave-flash),
|
69
|
-
block_all_mixed_content: true, # see http://www.w3.org/TR/mixed-content/
|
70
69
|
upgrade_insecure_requests: true, # see https://www.w3.org/TR/upgrade-insecure-requests/
|
71
70
|
report_uri: %w(https://report-uri.io/example-csp)
|
72
71
|
}
|
@@ -203,7 +203,7 @@ module SecureHeaders
|
|
203
203
|
raise IllegalPolicyModificationError, "You are attempting to modify CSP settings directly. Use dynamic_csp= instead."
|
204
204
|
end
|
205
205
|
|
206
|
-
@csp = new_csp
|
206
|
+
@csp = self.class.send(:deep_copy_if_hash, new_csp)
|
207
207
|
end
|
208
208
|
|
209
209
|
def cookies=(cookies)
|
@@ -215,7 +215,7 @@ module SecureHeaders
|
|
215
215
|
end
|
216
216
|
|
217
217
|
def hpkp=(hpkp)
|
218
|
-
@hpkp = hpkp
|
218
|
+
@hpkp = self.class.send(:deep_copy_if_hash, hpkp)
|
219
219
|
end
|
220
220
|
|
221
221
|
def hpkp_report_host=(hpkp_report_host)
|
@@ -1,18 +1,22 @@
|
|
1
1
|
require_relative 'policy_management'
|
2
|
+
require 'useragent'
|
2
3
|
|
3
4
|
module SecureHeaders
|
4
5
|
class ContentSecurityPolicyConfigError < StandardError; end
|
5
6
|
class ContentSecurityPolicy
|
6
7
|
include PolicyManagement
|
7
8
|
|
9
|
+
# constants to be used for version-specific UA sniffing
|
10
|
+
VERSION_46 = ::UserAgent::Version.new("46")
|
11
|
+
|
8
12
|
def initialize(config = nil, user_agent = OTHER)
|
9
|
-
config = Configuration.deep_copy
|
10
|
-
@config = config
|
13
|
+
@config = Configuration.send(:deep_copy, config || DEFAULT_CONFIG)
|
11
14
|
@parsed_ua = if user_agent.is_a?(UserAgent::Browsers::Base)
|
12
15
|
user_agent
|
13
16
|
else
|
14
17
|
UserAgent.parse(user_agent)
|
15
18
|
end
|
19
|
+
normalize_child_frame_src
|
16
20
|
@report_only = @config[:report_only]
|
17
21
|
@preserve_schemes = @config[:preserve_schemes]
|
18
22
|
@script_nonce = @config[:script_nonce]
|
@@ -42,6 +46,22 @@ module SecureHeaders
|
|
42
46
|
|
43
47
|
private
|
44
48
|
|
49
|
+
# frame-src is deprecated, child-src is being implemented. They are
|
50
|
+
# very similar and in most cases, the same value can be used for both.
|
51
|
+
def normalize_child_frame_src
|
52
|
+
if @config[:frame_src] && @config[:child_src] && @config[:frame_src] != @config[:child_src]
|
53
|
+
Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] both :child_src and :frame_src supplied and do not match. This can lead to inconsistent behavior across browsers.")
|
54
|
+
elsif @config[:frame_src]
|
55
|
+
Kernel.warn("#{Kernel.caller.first}: [DEPRECATION] :frame_src is deprecated, use :child_src instead. Provided: #{@config[:frame_src]}.")
|
56
|
+
end
|
57
|
+
|
58
|
+
if supported_directives.include?(:child_src)
|
59
|
+
@config[:child_src] = @config[:child_src] || @config[:frame_src]
|
60
|
+
else
|
61
|
+
@config[:frame_src] = @config[:frame_src] || @config[:child_src]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
45
65
|
# Private: converts the config object into a string representing a policy.
|
46
66
|
# Places default-src at the first directive and report-uri as the last. All
|
47
67
|
# others are presented in alphabetical order.
|
@@ -162,9 +182,19 @@ module SecureHeaders
|
|
162
182
|
|
163
183
|
# Private: determine which directives are supported for the given user agent.
|
164
184
|
#
|
185
|
+
# Add UA-sniffing special casing here.
|
186
|
+
#
|
165
187
|
# Returns an array of symbols representing the directives.
|
166
188
|
def supported_directives
|
167
|
-
@supported_directives ||= VARIATIONS[@parsed_ua.browser]
|
189
|
+
@supported_directives ||= if VARIATIONS[@parsed_ua.browser]
|
190
|
+
if @parsed_ua.browser == "Firefox" && @parsed_ua.version >= VERSION_46
|
191
|
+
VARIATIONS["FirefoxTransitional"]
|
192
|
+
else
|
193
|
+
VARIATIONS[@parsed_ua.browser]
|
194
|
+
end
|
195
|
+
else
|
196
|
+
VARIATIONS[OTHER]
|
197
|
+
end
|
168
198
|
end
|
169
199
|
|
170
200
|
def nonces_supported?
|
@@ -100,10 +100,23 @@ module SecureHeaders
|
|
100
100
|
PLUGIN_TYPES
|
101
101
|
].freeze
|
102
102
|
|
103
|
+
FIREFOX_46_DEPRECATED_DIRECTIVES = [
|
104
|
+
FRAME_SRC
|
105
|
+
].freeze
|
106
|
+
|
107
|
+
FIREFOX_46_UNSUPPORTED_DIRECTIVES = [
|
108
|
+
BLOCK_ALL_MIXED_CONTENT,
|
109
|
+
PLUGIN_TYPES
|
110
|
+
].freeze
|
111
|
+
|
103
112
|
FIREFOX_DIRECTIVES = (
|
104
113
|
DIRECTIVES_2_0 + DIRECTIVES_DRAFT - FIREFOX_UNSUPPORTED_DIRECTIVES
|
105
114
|
).freeze
|
106
115
|
|
116
|
+
FIREFOX_46_DIRECTIVES = (
|
117
|
+
DIRECTIVES_2_0 + DIRECTIVES_DRAFT - FIREFOX_46_UNSUPPORTED_DIRECTIVES - FIREFOX_46_DEPRECATED_DIRECTIVES
|
118
|
+
).freeze
|
119
|
+
|
107
120
|
CHROME_DIRECTIVES = (
|
108
121
|
DIRECTIVES_2_0 + DIRECTIVES_DRAFT
|
109
122
|
).freeze
|
@@ -118,6 +131,7 @@ module SecureHeaders
|
|
118
131
|
"Chrome" => CHROME_DIRECTIVES,
|
119
132
|
"Opera" => CHROME_DIRECTIVES,
|
120
133
|
"Firefox" => FIREFOX_DIRECTIVES,
|
134
|
+
"FirefoxTransitional" => FIREFOX_46_DIRECTIVES,
|
121
135
|
"Safari" => SAFARI_DIRECTIVES,
|
122
136
|
"Edge" => EDGE_DIRECTIVES,
|
123
137
|
"Other" => CHROME_DIRECTIVES
|
@@ -108,8 +108,6 @@ module SecureHeaders
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
115
|
-
end
|
111
|
+
ActiveSupport.on_load :action_view do
|
112
|
+
include SecureHeaders::ViewHelpers
|
113
|
+
end if defined?(ActiveSupport)
|
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.
|
4
|
+
gem.version = "3.4.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.'
|
@@ -24,7 +24,7 @@ module SecureHeaders
|
|
24
24
|
|
25
25
|
describe "#value" do
|
26
26
|
it "discards 'none' values if any other source expressions are present" do
|
27
|
-
csp = ContentSecurityPolicy.new(default_opts.merge(
|
27
|
+
csp = ContentSecurityPolicy.new(default_opts.merge(child_src: %w('self' 'none')))
|
28
28
|
expect(csp.value).not_to include("'none'")
|
29
29
|
end
|
30
30
|
|
@@ -86,42 +86,68 @@ module SecureHeaders
|
|
86
86
|
expect(csp.value).to eq("default-src example.org")
|
87
87
|
end
|
88
88
|
|
89
|
+
it "emits a warning when using frame-src" do
|
90
|
+
expect(Kernel).to receive(:warn).with(/:frame_src is deprecated, use :child_src instead./)
|
91
|
+
ContentSecurityPolicy.new(default_src: %w('self'), frame_src: %w('self')).value
|
92
|
+
end
|
93
|
+
|
94
|
+
it "emits a warning when child-src and frame-src are supplied but are not equal" do
|
95
|
+
expect(Kernel).to receive(:warn).with(/both :child_src and :frame_src supplied and do not match./)
|
96
|
+
ContentSecurityPolicy.new(default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)).value
|
97
|
+
end
|
98
|
+
|
99
|
+
it "will still set inconsistent child/frame-src values to be less surprising" do
|
100
|
+
expect(Kernel).to receive(:warn).at_least(:once)
|
101
|
+
firefox = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox]).value
|
102
|
+
firefox_transitional = ContentSecurityPolicy.new({default_src: %w('self'), child_src: %w(child-src.com), frame_src: %w(frame-src,com)}, USER_AGENTS[:firefox46]).value
|
103
|
+
expect(firefox).not_to eq(firefox_transitional)
|
104
|
+
expect(firefox).to match(/frame-src/)
|
105
|
+
expect(firefox).not_to match(/child-src/)
|
106
|
+
expect(firefox_transitional).to match(/child-src/)
|
107
|
+
expect(firefox_transitional).not_to match(/frame-src/)
|
108
|
+
end
|
109
|
+
|
89
110
|
context "browser sniffing" do
|
90
111
|
let (:complex_opts) do
|
91
|
-
ContentSecurityPolicy::ALL_DIRECTIVES.each_with_object({}) do |directive, hash|
|
92
|
-
hash[directive] =
|
112
|
+
(ContentSecurityPolicy::ALL_DIRECTIVES - [:frame_src]).each_with_object({}) do |directive, hash|
|
113
|
+
hash[directive] = ["#{directive.to_s.gsub("_", "-")}.com"]
|
93
114
|
end.merge({
|
94
115
|
block_all_mixed_content: true,
|
95
116
|
upgrade_insecure_requests: true,
|
96
117
|
reflected_xss: "block",
|
97
|
-
script_src: %w(
|
118
|
+
script_src: %w(script-src.com),
|
98
119
|
script_nonce: 123456
|
99
120
|
})
|
100
121
|
end
|
101
122
|
|
102
123
|
it "does not filter any directives for Chrome" do
|
103
124
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:chrome])
|
104
|
-
expect(policy.value).to eq("default-src
|
125
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
105
126
|
end
|
106
127
|
|
107
128
|
it "does not filter any directives for Opera" do
|
108
129
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:opera])
|
109
|
-
expect(policy.value).to eq("default-src
|
130
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; block-all-mixed-content; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; plugin-types plugin-types.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
110
131
|
end
|
111
132
|
|
112
133
|
it "filters blocked-all-mixed-content, child-src, and plugin-types for firefox" do
|
113
134
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox])
|
114
|
-
expect(policy.value).to eq("default-src
|
135
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "filters blocked-all-mixed-content, frame-src, and plugin-types for firefox 46 and higher" do
|
139
|
+
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:firefox46])
|
140
|
+
expect(policy.value).to eq("default-src default-src.com; base-uri base-uri.com; child-src child-src.com; connect-src connect-src.com; font-src font-src.com; form-action form-action.com; frame-ancestors frame-ancestors.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'nonce-123456'; style-src style-src.com; upgrade-insecure-requests; report-uri report-uri.com")
|
115
141
|
end
|
116
142
|
|
117
|
-
it "adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for Edge" do
|
143
|
+
it "child-src value is copied to frame-src, adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for Edge" do
|
118
144
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:edge])
|
119
|
-
expect(policy.value).to eq("default-src
|
145
|
+
expect(policy.value).to eq("default-src default-src.com; connect-src connect-src.com; font-src font-src.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'unsafe-inline'; style-src style-src.com; report-uri report-uri.com")
|
120
146
|
end
|
121
147
|
|
122
|
-
it "adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for safari" do
|
148
|
+
it "child-src value is copied to frame-src, adds 'unsafe-inline', filters base-uri, blocked-all-mixed-content, upgrade-insecure-requests, child-src, form-action, frame-ancestors, nonce sources, hash sources, and plugin-types for safari" do
|
123
149
|
policy = ContentSecurityPolicy.new(complex_opts, USER_AGENTS[:safari6])
|
124
|
-
expect(policy.value).to eq("default-src
|
150
|
+
expect(policy.value).to eq("default-src default-src.com; connect-src connect-src.com; font-src font-src.com; frame-src child-src.com; img-src img-src.com; media-src media-src.com; object-src object-src.com; sandbox sandbox.com; script-src script-src.com 'unsafe-inline'; style-src style-src.com; report-uri report-uri.com")
|
125
151
|
end
|
126
152
|
end
|
127
153
|
end
|
@@ -23,7 +23,8 @@ module SecureHeaders
|
|
23
23
|
# directive values: these values will directly translate into source directives
|
24
24
|
default_src: %w(https: 'self'),
|
25
25
|
frame_src: %w('self' *.twimg.com itunes.apple.com),
|
26
|
-
|
26
|
+
child_src: %w('self' *.twimg.com itunes.apple.com),
|
27
|
+
connect_src: %w(wss:),
|
27
28
|
font_src: %w('self' data:),
|
28
29
|
img_src: %w(mycdn.com data:),
|
29
30
|
media_src: %w(utoob.com),
|
@@ -31,7 +32,6 @@ module SecureHeaders
|
|
31
32
|
script_src: %w('self'),
|
32
33
|
style_src: %w('unsafe-inline'),
|
33
34
|
base_uri: %w('self'),
|
34
|
-
child_src: %w('self'),
|
35
35
|
form_action: %w('self' github.com),
|
36
36
|
frame_ancestors: %w('none'),
|
37
37
|
plugin_types: %w(application/x-shockwave-flash),
|
@@ -90,8 +90,7 @@ module SecureHeaders
|
|
90
90
|
config = Configuration.default do |config|
|
91
91
|
config.csp = {
|
92
92
|
default_src: %w('self'),
|
93
|
-
child_src: %w('self')
|
94
|
-
frame_src: %w('self')
|
93
|
+
child_src: %w('self')
|
95
94
|
}
|
96
95
|
end
|
97
96
|
firefox_request = Rack::Request.new(request.env.merge("HTTP_USER_AGENT" => USER_AGENTS[:firefox]))
|
@@ -102,6 +101,8 @@ module SecureHeaders
|
|
102
101
|
SecureHeaders.override_content_security_policy_directives(firefox_request, script_src: %w('self'))
|
103
102
|
|
104
103
|
hash = SecureHeaders.header_hash_for(firefox_request)
|
104
|
+
|
105
|
+
# child-src is translated to frame-src
|
105
106
|
expect(hash[CSP::HEADER_NAME]).to eq("default-src 'self'; frame-src 'self'; script-src 'self'")
|
106
107
|
end
|
107
108
|
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,8 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'secure_headers')
|
|
12
12
|
|
13
13
|
USER_AGENTS = {
|
14
14
|
edge: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
|
15
|
-
firefox:
|
15
|
+
firefox: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1",
|
16
|
+
firefox46: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:46.0) Gecko/20100101 Firefox/46.0",
|
16
17
|
chrome: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5',
|
17
18
|
ie: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)',
|
18
19
|
opera: 'Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00',
|
data/upgrading-to-3-0.md
CHANGED
@@ -8,7 +8,7 @@ Changes
|
|
8
8
|
| Global configuration | `SecureHeaders::Configuration.configure` block | `SecureHeaders::Configuration.default` block |
|
9
9
|
| All headers besides HPKP and CSP | Accept hashes as config values | Must be strings (validated during configuration) |
|
10
10
|
| CSP directive values | Accepted space delimited strings OR arrays of strings | Must be arrays of strings |
|
11
|
-
| CSP Nonce values in views | `@content_security_policy_nonce` | `
|
11
|
+
| CSP Nonce values in views | `@content_security_policy_nonce` | `content_security_policy_nonce(:script)` or `content_security_policy_nonce(:style)` |
|
12
12
|
| nonce is no longer a source expression | `config.csp = "'self' 'nonce'"` | Remove `'nonce'` from source expression and use [nonce helpers](https://github.com/twitter/secureheaders#nonce). |
|
13
13
|
| `self`/`none` source expressions | Could be `self` / `none` / `'self'` / `'none'` | Must be `'self'` or `'none'` |
|
14
14
|
| `inline` / `eval` source expressions | Could be `inline`, `eval`, `'unsafe-inline'`, or `'unsafe-eval'` | Must be `'unsafe-eval'` or `'unsafe-inline'` |
|
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.
|
4
|
+
version: 3.4.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-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -45,6 +45,8 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
+
- ".github/ISSUE_TEMPLATE.md"
|
49
|
+
- ".github/PULL_REQUEST_TEMPLATE.md"
|
48
50
|
- ".gitignore"
|
49
51
|
- ".rspec"
|
50
52
|
- ".ruby-gemset"
|