secure_headers 0.2.1 → 0.3.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.
- data/HISTORY.md +14 -0
- data/README.md +6 -9
- data/lib/secure_headers/headers/content_security_policy/browser_strategy.rb +5 -1
- data/lib/secure_headers/headers/content_security_policy/webkit_browser_strategy.rb +9 -0
- data/lib/secure_headers/headers/content_security_policy.rb +14 -15
- data/lib/secure_headers/version.rb +1 -1
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +37 -5
- metadata +2 -2
data/HISTORY.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
0.3.0
|
2
|
+
=======
|
3
|
+
- Greatly reduce the need to use the forward_endpoint attribute. If you are posting from your site to a host that matches TLD+1 (e.g. translate.twitter.com matches twitter.com), use a protocol relative value for report-uri. This will alleviate the need to use forwarding. If your host doesn't match, you still need to use forwarding due to host mismatches for Firefox.
|
4
|
+
|
5
|
+
0.2.3
|
6
|
+
=======
|
7
|
+
|
8
|
+
- Fix error in report-uri logic for Firefox forwarding.
|
9
|
+
|
10
|
+
0.2.2
|
11
|
+
=======
|
12
|
+
|
13
|
+
- Stop applying chrome-extension: to Firefox directives.
|
14
|
+
|
1
15
|
0.2.1
|
2
16
|
=======
|
3
17
|
|
data/README.md
CHANGED
@@ -59,8 +59,7 @@ This gem makes a few assumptions about how you will use some features. For exam
|
|
59
59
|
config.x_xss_protection = {:value => '1', :mode => false}
|
60
60
|
config.csp = {
|
61
61
|
:default_src => "https://* inline eval",
|
62
|
-
|
63
|
-
:report_uri => 'https://example.com/uri-directive',
|
62
|
+
:report_uri => '//example.com/uri-directive',
|
64
63
|
:img_src => "https://* data:",
|
65
64
|
:frame_src => "https://* http://*.twimg.com http://itunes.apple.com"
|
66
65
|
}
|
@@ -107,12 +106,12 @@ and [Mozilla CSP specification](https://wiki.mozilla.org/Security/CSP/Specificat
|
|
107
106
|
# default_src is required!
|
108
107
|
:default_src => nil, # sets the default-src/allow+options directives
|
109
108
|
|
110
|
-
# Where reports are sent. Use
|
111
|
-
:report_uri => '
|
109
|
+
# Where reports are sent. Use protocol relative URLs if you are posting to the same domain (TLD+1). Use paths if you are posting to the application serving the header
|
110
|
+
:report_uri => '//mysite.example.com',
|
112
111
|
|
113
112
|
# Send reports that cannot be sent across host here. These requests are sent
|
114
113
|
# the server, not the browser. If no value is supplied, it will default to
|
115
|
-
# the value in report_uri.
|
114
|
+
# the value in report_uri. Use this if you cannot use relative protocols mentioned above due to host mismatches.
|
116
115
|
:forward_endpoint => 'https://internal.mylogaggregator.example.com'
|
117
116
|
|
118
117
|
# these directives all take 'none', 'self', or a globbed pattern
|
@@ -239,8 +238,7 @@ require 'secure_headers'
|
|
239
238
|
config.x_xss_protection = {:value => '1', :mode => false}
|
240
239
|
config.csp = {
|
241
240
|
:default_src => "https://* inline eval",
|
242
|
-
|
243
|
-
:report_uri => 'https://example.com/uri-directive',
|
241
|
+
:report_uri => '//example.com/uri-directive',
|
244
242
|
:img_src => "https://* data:",
|
245
243
|
:frame_src => "https://* http://*.twimg.com http://itunes.apple.com"
|
246
244
|
}
|
@@ -281,8 +279,7 @@ module Web
|
|
281
279
|
config.x_xss_protection = {:value => '1', :mode => false}
|
282
280
|
config.csp = {
|
283
281
|
:default_src => "https://* inline eval",
|
284
|
-
|
285
|
-
:report_uri => 'https://example.com/uri-directive',
|
282
|
+
:report_uri => '//example.com/uri-directive',
|
286
283
|
:img_src => "https://* data:",
|
287
284
|
:frame_src => "https://* http://*.twimg.com http://itunes.apple.com"
|
288
285
|
}
|
@@ -4,6 +4,15 @@ module SecureHeaders
|
|
4
4
|
def base_name
|
5
5
|
SecureHeaders::ContentSecurityPolicy::WEBKIT_CSP_HEADER_NAME
|
6
6
|
end
|
7
|
+
|
8
|
+
def add_missing_extension_values
|
9
|
+
directives.each do |directive|
|
10
|
+
next unless config[directive]
|
11
|
+
if !config[directive].include?('chrome-extension:')
|
12
|
+
config[directive] << 'chrome-extension:'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
7
16
|
end
|
8
17
|
end
|
9
18
|
end
|
@@ -97,13 +97,13 @@ module SecureHeaders
|
|
97
97
|
|
98
98
|
def build_value
|
99
99
|
fill_directives unless disable_fill_missing?
|
100
|
-
|
100
|
+
browser_strategy.add_missing_extension_values unless disable_chrome_extension?
|
101
101
|
append_http_additions unless ssl_request?
|
102
102
|
|
103
103
|
header_value = [
|
104
104
|
build_impl_specific_directives,
|
105
105
|
generic_directives(@config),
|
106
|
-
report_uri_directive
|
106
|
+
report_uri_directive
|
107
107
|
].join
|
108
108
|
|
109
109
|
#store the value for next time
|
@@ -125,15 +125,6 @@ module SecureHeaders
|
|
125
125
|
@config
|
126
126
|
end
|
127
127
|
|
128
|
-
def add_missing_chrome_extension_values
|
129
|
-
directives.each do |directive|
|
130
|
-
next unless @config[directive]
|
131
|
-
if !@config[directive].include?('chrome-extension:')
|
132
|
-
@config[directive] << 'chrome-extension:'
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
128
|
def append_http_additions
|
138
129
|
return unless http_additions
|
139
130
|
|
@@ -183,8 +174,6 @@ module SecureHeaders
|
|
183
174
|
|
184
175
|
if forward_endpoint
|
185
176
|
@report_uri = FF_CSP_ENDPOINT
|
186
|
-
else
|
187
|
-
@report_uri = nil
|
188
177
|
end
|
189
178
|
end
|
190
179
|
|
@@ -205,8 +194,18 @@ module SecureHeaders
|
|
205
194
|
uri.host == origin.host && origin.port == uri.port && origin.scheme == uri.scheme
|
206
195
|
end
|
207
196
|
|
208
|
-
def report_uri_directive
|
209
|
-
|
197
|
+
def report_uri_directive
|
198
|
+
return '' if @report_uri.nil?
|
199
|
+
|
200
|
+
if @report_uri.start_with?('//')
|
201
|
+
@report_uri = if @ssl_request
|
202
|
+
"https:" + @report_uri
|
203
|
+
else
|
204
|
+
"http:" + @report_uri
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
"report-uri #{@report_uri};"
|
210
209
|
end
|
211
210
|
|
212
211
|
def generic_directives(config)
|
@@ -10,7 +10,7 @@ module SecureHeaders
|
|
10
10
|
:default_src => 'https://*',
|
11
11
|
:report_uri => '/csp_report',
|
12
12
|
:script_src => 'inline eval https://* data:',
|
13
|
-
:style_src => "inline https://*
|
13
|
+
:style_src => "inline https://* about:"
|
14
14
|
}
|
15
15
|
end
|
16
16
|
|
@@ -186,6 +186,33 @@ module SecureHeaders
|
|
186
186
|
csp = ContentSecurityPolicy.new(opts, :request => request_for(CHROME))
|
187
187
|
csp.report_uri.should == 'https://example.com/csp'
|
188
188
|
end
|
189
|
+
|
190
|
+
context "when using a protocol-relative value for report-uri" do
|
191
|
+
let(:opts) {
|
192
|
+
{
|
193
|
+
:default_src => 'self',
|
194
|
+
:report_uri => '//example.com/csp'
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
it "uses the current protocol" do
|
199
|
+
csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX, '/', :ssl => true))
|
200
|
+
csp.value.should =~ %r{report-uri https://example.com/csp;}
|
201
|
+
|
202
|
+
csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX))
|
203
|
+
csp.value.should =~ %r{report-uri http://example.com/csp;}
|
204
|
+
end
|
205
|
+
|
206
|
+
it "uses the pre-configured https protocol" do
|
207
|
+
csp = ContentSecurityPolicy.new(opts, :ua => "Firefox", :ssl => true)
|
208
|
+
csp.value.should =~ %r{report-uri https://example.com/csp;}
|
209
|
+
end
|
210
|
+
|
211
|
+
it "uses the pre-configured http protocol" do
|
212
|
+
csp = ContentSecurityPolicy.new(opts, :ua => "Firefox", :ssl => false)
|
213
|
+
csp.value.should =~ %r{report-uri http://example.com/csp;}
|
214
|
+
end
|
215
|
+
end
|
189
216
|
end
|
190
217
|
|
191
218
|
describe "#value" do
|
@@ -212,7 +239,7 @@ module SecureHeaders
|
|
212
239
|
it "fills in directives without values with default-src value" do
|
213
240
|
options = default_opts.merge(:disable_fill_missing => false)
|
214
241
|
csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
|
215
|
-
value = "default-src https://*; connect-src https://*; font-src https://*; frame-src https://*; img-src https://* data:; media-src https://*; object-src https://*; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://*
|
242
|
+
value = "default-src https://*; connect-src https://*; font-src https://*; frame-src https://*; img-src https://* data:; media-src https://*; object-src https://*; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
|
216
243
|
csp.value.should == value
|
217
244
|
end
|
218
245
|
|
@@ -224,7 +251,12 @@ module SecureHeaders
|
|
224
251
|
context "X-Content-Security-Policy" do
|
225
252
|
it "builds a csp header for firefox" do
|
226
253
|
csp = ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX))
|
227
|
-
csp.value.should == "allow https://*; options inline-script eval-script; img-src data:; script-src https://* data:; style-src https://*
|
254
|
+
csp.value.should == "allow https://*; options inline-script eval-script; img-src data:; script-src https://* data:; style-src https://* about:; report-uri /csp_report;"
|
255
|
+
end
|
256
|
+
|
257
|
+
it "does not append chrome-extension to directives" do
|
258
|
+
csp = ContentSecurityPolicy.new(default_opts.merge(:disable_chrome_extension => false), :request => request_for(FIREFOX))
|
259
|
+
csp.value.should_not match "chrome-extension:"
|
228
260
|
end
|
229
261
|
|
230
262
|
it "copies connect-src values to xhr_src values" do
|
@@ -253,7 +285,7 @@ module SecureHeaders
|
|
253
285
|
context "X-Webkit-CSP" do
|
254
286
|
it "builds a csp header for chrome" do
|
255
287
|
csp = ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME))
|
256
|
-
csp.value.should == "default-src https://*; img-src data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://*
|
288
|
+
csp.value.should == "default-src https://*; img-src data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
|
257
289
|
end
|
258
290
|
|
259
291
|
it "ignores :forward_endpoint settings" do
|
@@ -311,7 +343,7 @@ module SecureHeaders
|
|
311
343
|
|
312
344
|
it "adds directive values for headers on http" do
|
313
345
|
csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
|
314
|
-
csp.value.should == "default-src https://*; frame-src http://*; img-src http://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://*
|
346
|
+
csp.value.should == "default-src https://*; frame-src http://*; img-src http://* data:; script-src 'unsafe-inline' 'unsafe-eval' https://* data:; style-src 'unsafe-inline' https://* about:; report-uri /csp_report;"
|
315
347
|
end
|
316
348
|
|
317
349
|
it "does not add the directive values if requesting https" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: secure_headers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-03-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: brwsr
|