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 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