secure_headers 0.2.1 → 0.3.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.

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
- # ALWAYS supply a full URL for report URIs
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 full URLs.
111
- :report_uri => 'https://mylogaggregator.example.com',
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
- # ALWAYS supply a full URL for report URIs
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
- # ALWAYS supply a full URL for report URIs
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
  }
@@ -63,7 +63,11 @@ module SecureHeaders
63
63
  end
64
64
 
65
65
  def normalize_reporting_endpoint?
66
- false
66
+ # noop except for Firefox for now
67
+ end
68
+
69
+ def add_missing_extension_values
70
+ # noop except for chrome for now
67
71
  end
68
72
  end
69
73
  end
@@ -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
- add_missing_chrome_extension_values unless disable_chrome_extension?
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(@report_uri)
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(report_uri)
209
- report_uri ? "report-uri #{report_uri};" : ''
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)
@@ -1,3 +1,3 @@
1
1
  module SecureHeaders
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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://* chrome-extension: about:"
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://* chrome-extension: about:; report-uri /csp_report;"
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://* chrome-extension: about:; report-uri /csp_report;"
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://* chrome-extension: about:; report-uri /csp_report;"
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://* chrome-extension: about:; report-uri /csp_report;"
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.2.1
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-02-21 00:00:00.000000000 Z
12
+ date: 2013-03-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: brwsr