secure_headers 1.0.0 → 1.1.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/Gemfile CHANGED
@@ -7,8 +7,11 @@ group :test do
7
7
  gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
8
8
  gem 'jdbc-sqlite3', :platform => :jruby
9
9
  gem 'rspec-rails'
10
- gem 'guard-spork'
11
- gem 'guard-rspec'
10
+ gem 'spork'
11
+ gem 'pry'
12
+ gem 'rspec'
13
+ gem 'guard-spork', :platform => :ruby_19
14
+ gem 'guard-rspec', :platform => :ruby_19
12
15
  gem 'growl'
13
16
  gem 'rb-fsevent'
14
17
  gem 'simplecov'
data/HISTORY.md CHANGED
@@ -1,3 +1,11 @@
1
+ 1.1.0
2
+ ======
3
+
4
+ - Remove brwsr dependency (no more runtime dependencies)
5
+ - Stop serving X- prefixed CSP headers
6
+
7
+ This change means that all requests get all headers, even if the browser doesn't grok it.
8
+
1
9
  1.0.0
2
10
  ======
3
11
 
data/README.md CHANGED
@@ -49,13 +49,11 @@ The following methods are going to be called, unless they are provided in a `ski
49
49
  * `:set_x_xss_protection_header`
50
50
  * `:set_x_content_type_options_header`
51
51
 
52
- ### Automagic
52
+ ### Bonus Features
53
53
 
54
54
  This gem makes a few assumptions about how you will use some features. For example:
55
55
 
56
- * It adds 'chrome-extension:' to your CSP directives by default. This helps drastically reduce the amount of reports, but you can also disable this feature by supplying `:disable_chrome_extension => true`.
57
- * It fills any blank directives with the value in `:default_src` Getting a default\-src report is pretty useless. This way, you will always know what type of violation occurred. You can disable this feature by supplying `:disable_fill_missing => true`.
58
- * It copies the connect\-src value to xhr\-src for AJAX requests when using Firefox.
56
+ * It fills any blank directives with the value in `:default_src` Getting a default\-src report is pretty useless. This way, you will always know what type of violation occurred. You can disable this feature by supplying `:disable_fill_missing => true`. This is referred to as the "effective-directive" in the spec, but is not well supported as of Nov 5, 2013.
59
57
  * Firefox does not support cross\-origin CSP reports. If we are using Firefox, AND the value for `:report_uri` does not satisfy the same\-origin requirements, we will instead forward to an internal endpoint (`FF_CSP_ENDPOINT`). This is also the case if `:report_uri` only contains a path, which we assume will be cross host. This endpoint will in turn forward the request to the value in `:forward_endpoint` without restriction. More information can be found in the "Note on Firefox handling of CSP" section.
60
58
 
61
59
 
@@ -65,29 +63,31 @@ This gem makes a few assumptions about how you will use some features. For exam
65
63
 
66
64
  ```ruby
67
65
  ::SecureHeaders::Configuration.configure do |config|
68
- config.hsts = {:max_age => 99, :include_subdomains => true}
66
+ config.hsts = {:max_age => 20.years.to_i, :include_subdomains => true}
69
67
  config.x_frame_options = 'DENY'
70
68
  config.x_content_type_options = "nosniff"
71
- config.x_xss_protection = {:value => 1, :mode => false}
69
+ config.x_xss_protection = {:value => 1, :mode => 'block'}
72
70
  config.csp = {
73
- :default_src => "https://* inline eval",
74
- :report_uri => '//example.com/uri-directive',
75
- :img_src => "https://* data:",
76
- :frame_src => "https://* http://*.twimg.com http://itunes.apple.com"
71
+ :default_src => "https://* self",
72
+ :frame_src => "https://* http://*.twimg.com http://itunes.apple.com",
73
+ :img_src => "https://*",
74
+ :report_uri => '//example.com/uri-directive'
77
75
  }
78
76
  end
79
77
 
80
- # and then simply include this in application_controller
81
- ensure_security_headers
78
+ # and then simply include this in application_controller.rb
79
+ class ApplicationController < ActionController::Base
80
+ ensure_security_headers
81
+ end
82
82
  ```
83
83
 
84
- Or simply add it to application controller (not recommended, currently a bug)
84
+ Or simply add it to application controller
85
85
 
86
86
  ```ruby
87
- ensure_security_headers
87
+ ensure_security_headers(
88
88
  :hsts => {:include_subdomains, :x_frame_options => false},
89
89
  :x_frame_options => 'DENY',
90
- :csp => false
90
+ :csp => false)
91
91
  ```
92
92
 
93
93
  ## Options for ensure\_security\_headers
@@ -98,12 +98,15 @@ Each header configuration can take a hash, or a string, or both. If a string
98
98
  is provided, that value is inserted verbatim. If a hash is supplied, a
99
99
  header will be constructed using the supplied options.
100
100
 
101
- ### Widely supported
101
+ ### The Easy Headers
102
+
103
+ This configuration will likely work for most applications without modification.
102
104
 
103
105
  ```ruby
104
- :hsts => {:max_age => 631138519, :include_subdomains => true}
106
+ :hsts => {:max_age => 631138519, :include_subdomains => false}
105
107
  :x_frame_options => {:value => 'SAMEORIGIN'}
106
- :x_xss_protection => {:value => 1, :mode => false} # set the :mode option to 'block' to enforce the browser's xss filter
108
+ :x_xss_protection => {:value => 1, :mode => 'block'} # set the :mode option to false to use "warning only" mode
109
+ :x_content_type_options => {:value => 'nosniff'}
107
110
  ```
108
111
 
109
112
  ### Content Security Policy (CSP)
@@ -159,28 +162,18 @@ and [Mozilla CSP specification](https://wiki.mozilla.org/Security/CSP/Specificat
159
162
  :img_src => 'http://mycdn.example.com'
160
163
  }
161
164
  }
162
-
165
+
163
166
  # script-nonce is an experimental feature of CSP 1.1 available in Chrome. It allows
164
167
  # you to whitelist inline script blocks. For more information, see
165
168
  # https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-nonce
166
- :script_nonce => { 'abc123' }
167
-
168
- # you can also use lambdas to use dynamically generated nonces
169
- :script_nonce => lambda { @script_nonce] = 'something' }
169
+ :script_nonce => lambda { @script_nonce = SecureRandom.hex }
170
170
  # which can be used to whitelist a script block:
171
171
  # script_tag :nonce = @script_nonce { inline_script_call() }
172
172
  }
173
173
  ```
174
174
 
175
- ### Only applied to IE
176
-
177
- ```ruby
178
- :x_content_type_options => {:value => 'nosniff'}
179
- ```
180
-
181
175
  ### Example CSP header config
182
176
 
183
- **Configure the CSP header as if it were the webkit-style header, no need to supply 'options' or 'allow' directives.**
184
177
 
185
178
  ```ruby
186
179
  # most basic example
@@ -188,20 +181,16 @@ and [Mozilla CSP specification](https://wiki.mozilla.org/Security/CSP/Specificat
188
181
  :default_src => "https://* inline eval",
189
182
  :report_uri => '/uri-directive'
190
183
  }
191
- # Chrome
192
- > "default-src 'unsafe-inline' 'unsafe-eval' https://* chrome-extension:; report-uri /uri-directive;"
193
- # Firefox
194
- > "options inline-script eval-script; allow https://*; report-uri /uri-directive;"
184
+
185
+ > "default-src 'unsafe-inline' 'unsafe-eval' https://*; report-uri /uri-directive;"
195
186
 
196
187
  # turn off inline scripting/eval
197
188
  :csp => {
198
189
  :default_src => 'https://*',
199
190
  :report_uri => '/uri-directive'
200
191
  }
201
- # Chrome
192
+
202
193
  > "default-src https://*; report-uri /uri-directive;"
203
- # Firefox
204
- > "allow https://*; report-uri /uri-directive;"
205
194
 
206
195
  # Auction site wants to allow images from anywhere, plugin content from a list of trusted media providers (including a content distribution network), and scripts only from its server hosting sanitized JavaScript
207
196
  :csp => {
@@ -211,19 +200,14 @@ and [Mozilla CSP specification](https://wiki.mozilla.org/Security/CSP/Specificat
211
200
  # alternatively (NOT csv) :object_src => 'media1.com media2.com *.cdn.com'
212
201
  :script_src => 'trustedscripts.example.com'
213
202
  }
214
- # Chrome
215
203
  "default-src 'self'; img-src *; object-src media1.com media2.com *.cdn.com; script-src trustedscripts.example.com;"
216
- # Firefox
217
- "allow 'self'; img-src *; object-src media1.com media2.com *.cdn.com; script-src trustedscripts.example.com;"
218
204
  ```
219
205
 
220
206
  ## Note on Firefox handling of CSP
221
207
 
222
208
  Currently, Firefox does not support the w3c draft standard. So there are a few steps taken to make the two interchangeable.
223
209
 
224
- * inline\-script or eval\-script values in default/style/script\-src directives are moved to the options directive. Note: the style\-src directive is not fully supported in Firefox \- see https://bugzilla.mozilla.org/show_bug.cgi?id=763879.
225
210
  * CSP reports will not POST cross\-origin. This sets up an internal endpoint in the application that will forward the request. Set the `forward_endpoint` value in the CSP section if you need to post cross origin for firefox. The internal endpoint that receives the initial request will forward the request to `forward_endpoint`
226
- * Ffirefox adds port numbers to each /https?/ value which can make local development tricky with mocked services. Add environment specific code to configure this.
227
211
 
228
212
  ### Adding the Firefox report forwarding endpoint
229
213
 
@@ -315,6 +299,13 @@ module Web
315
299
  end
316
300
  ```
317
301
 
302
+ ## Similar libraries
303
+
304
+ * Node.js (express) [helmet](https://github.com/evilpacket/helmet) and [hood](https://github.com/seanmonstar/hood)
305
+ * J2EE Servlet >= 3.0 [highlines](https://github.com/sourceclear/headlines)
306
+ * ASP.NET - [NWebsec](http://nwebsec.codeplex.com/)
307
+ * Python - [django-csp](https://github.com/mozilla/django-csp/tree/master/csp) + [commonware](https://github.com/jsocol/commonware/tree/master/commonware/request)
308
+ * Go - [secureheader](https://github.com/kr/secureheader)
318
309
 
319
310
  ## Authors
320
311
 
@@ -19,7 +19,7 @@ describe OtherThingsController do
19
19
 
20
20
  it "sets the X-WebKit-CSP header" do
21
21
  get :index
22
- response.headers['X-WebKit-CSP-Report-Only'].should == "default-src 'self'; img-src data:; report-uri somewhere;"
22
+ response.headers['Content-Security-Policy-Report-Only'].should == "default-src 'self'; img-src data:; report-uri somewhere;"
23
23
  end
24
24
 
25
25
  #mock ssl
@@ -23,7 +23,7 @@ describe ThingsController do
23
23
 
24
24
  it "sets the X-WebKit-CSP header" do
25
25
  get :index
26
- response.headers['X-WebKit-CSP-Report-Only'].should == nil
26
+ response.headers['Content-Security-Policy-Report-Only'].should == nil
27
27
  end
28
28
 
29
29
  #mock ssl
@@ -47,6 +47,3 @@ describe ThingsController do
47
47
  end
48
48
  end
49
49
  end
50
-
51
-
52
- # response.headers['X-WebKit-CSP-Report-Only'].should == "default-src 'self'; report-uri somewhere"
@@ -19,7 +19,7 @@ describe OtherThingsController do
19
19
 
20
20
  it "sets the X-WebKit-CSP header" do
21
21
  get :index
22
- response.headers['X-WebKit-CSP-Report-Only'].should == "default-src 'self'; img-src data:;"
22
+ response.headers['Content-Security-Policy-Report-Only'].should == "default-src 'self'; img-src data:;"
23
23
  end
24
24
 
25
25
  #mock ssl
@@ -23,7 +23,7 @@ describe ThingsController do
23
23
 
24
24
  it "sets the X-WebKit-CSP header" do
25
25
  get :index
26
- response.headers['X-WebKit-CSP-Report-Only'].should == nil
26
+ response.headers['Content-Security-Policy-Report-Only'].should == nil
27
27
  end
28
28
 
29
29
  #mock ssl
@@ -48,8 +48,13 @@ module SecureHeaders
48
48
  end
49
49
 
50
50
  module InstanceMethods
51
- def brwsr
52
- @secure_headers_brwsr ||= Brwsr::Browser.new(:ua => request.env['HTTP_USER_AGENT'])
51
+ # Re-added for backwards compat.
52
+ def set_security_headers(options = self.class.secure_headers_options)
53
+ set_csp_header(request, options[:csp])
54
+ set_hsts_header(options[:hsts])
55
+ set_x_frame_options_header(options[:x_frame_options])
56
+ set_x_xss_protection_header(options[:x_xss_protection])
57
+ set_x_content_type_options_header(options[:x_content_type_options])
53
58
  end
54
59
 
55
60
  # backwards compatibility jank, to be removed in 1.0. Old API required a request
@@ -59,12 +64,9 @@ module SecureHeaders
59
64
  # set_csp_header(+Hash+) - uses the request accessor and options from parameters
60
65
  # set_csp_header(+Rack::Request+, +Hash+)
61
66
  def set_csp_header(req = nil, options=nil)
62
- return if broken_implementation?(brwsr)
63
-
67
+ # hack to help generating headers statically
64
68
  if req.is_a?(Hash)
65
69
  options = req
66
- elsif req
67
- @secure_headers_brwsr = Brwsr::Browser.new(:ua => req.env['HTTP_USER_AGENT'])
68
70
  end
69
71
 
70
72
  options = self.class.secure_headers_options[:csp] if options.nil?
@@ -85,7 +87,6 @@ module SecureHeaders
85
87
  end
86
88
 
87
89
  def set_x_content_type_options_header(options=self.class.secure_headers_options[:x_content_type_options])
88
- return unless brwsr.ie? || brwsr.chrome?
89
90
  set_a_header(:x_content_type_options, XContentTypeOptions, options)
90
91
  end
91
92
 
@@ -116,10 +117,6 @@ module SecureHeaders
116
117
  response.headers[name_or_header] = value
117
118
  end
118
119
  end
119
-
120
- def broken_implementation?(browser)
121
- return browser.ios5? || (browser.safari? && browser.version == '5')
122
- end
123
120
  end
124
121
  end
125
122
 
@@ -127,13 +124,8 @@ end
127
124
  require "secure_headers/version"
128
125
  require "secure_headers/header"
129
126
  require "secure_headers/headers/content_security_policy"
130
- require "secure_headers/headers/content_security_policy/browser_strategy"
131
- require "secure_headers/headers/content_security_policy/firefox_browser_strategy"
132
- require "secure_headers/headers/content_security_policy/ie_browser_strategy"
133
- require "secure_headers/headers/content_security_policy/standard_browser_strategy"
134
127
  require "secure_headers/headers/x_frame_options"
135
128
  require "secure_headers/headers/strict_transport_security"
136
129
  require "secure_headers/headers/x_xss_protection"
137
130
  require "secure_headers/headers/x_content_type_options"
138
131
  require "secure_headers/railtie"
139
- require "brwsr"
@@ -1,26 +1,19 @@
1
1
  require 'uri'
2
- require 'brwsr'
3
2
 
4
3
  module SecureHeaders
5
4
  class ContentSecurityPolicyBuildError < StandardError; end
6
5
  class ContentSecurityPolicy < Header
7
6
  module Constants
8
- WEBKIT_CSP_HEADER = "default-src https: data: 'unsafe-inline' 'unsafe-eval'; frame-src https://* about: javascript:; img-src chrome-extension:"
9
- FIREFOX_CSP_HEADER = "options eval-script inline-script; allow https://* data:; frame-src https://* about: javascript:; img-src chrome-extension:"
10
-
11
- FIREFOX_CSP_HEADER_NAME = 'X-Content-Security-Policy'
12
- WEBKIT_CSP_HEADER_NAME = 'X-WebKit-CSP'
7
+ DEFAULT_CSP_HEADER = "default-src https: data: 'unsafe-inline' 'unsafe-eval'; frame-src https://* about: javascript:; img-src data:"
13
8
  STANDARD_HEADER_NAME = "Content-Security-Policy"
14
-
15
9
  FF_CSP_ENDPOINT = "/content_security_policy/forward_report"
16
- WEBKIT_DIRECTIVES = DIRECTIVES = [:default_src, :script_src, :frame_src, :style_src, :img_src, :media_src, :font_src, :object_src, :connect_src]
17
- FIREFOX_DIRECTIVES = DIRECTIVES + [:xhr_src, :frame_ancestors] - [:connect_src]
10
+ DIRECTIVES = [:default_src, :script_src, :frame_src, :style_src, :img_src, :media_src, :font_src, :object_src, :connect_src]
18
11
  META = [:enforce, :http_additions, :disable_chrome_extension, :disable_fill_missing, :forward_endpoint]
19
12
  end
20
13
  include Constants
21
14
 
22
15
  attr_accessor *META
23
- attr_reader :browser, :ssl_request, :report_uri, :request_uri, :experimental, :config
16
+ attr_reader :browser, :ssl_request, :report_uri, :request_uri, :experimental
24
17
 
25
18
  alias :disable_chrome_extension? :disable_chrome_extension
26
19
  alias :disable_fill_missing? :disable_fill_missing
@@ -40,7 +33,7 @@ module SecureHeaders
40
33
  if options[:request]
41
34
  parse_request(options[:request])
42
35
  else
43
- @browser = Brwsr::Browser.new(:ua => options[:ua])
36
+ @ua = options[:ua]
44
37
  # fails open, assumes http. Bad idea? Will always include http additions.
45
38
  # could also fail if not supplied.
46
39
  @ssl_request = !!options.delete(:ssl)
@@ -52,8 +45,8 @@ module SecureHeaders
52
45
  configure(config) if config
53
46
  end
54
47
 
55
- def configure opts
56
- @config = opts.dup
48
+ def configure(config)
49
+ @config = config.dup
57
50
 
58
51
  experimental_config = @config.delete(:experimental)
59
52
  if @experimental && experimental_config
@@ -70,40 +63,34 @@ module SecureHeaders
70
63
 
71
64
  normalize_csp_options
72
65
  normalize_reporting_endpoint
73
- filter_unsupported_directives
66
+ fill_directives unless disable_fill_missing?
74
67
  end
75
68
 
76
69
  def name
77
- browser_strategy.name
70
+ base = STANDARD_HEADER_NAME
71
+ if !enforce || experimental
72
+ base += "-Report-Only"
73
+ end
74
+ base
78
75
  end
79
76
 
80
77
  def value
81
78
  return @config if @config.is_a?(String)
82
-
83
79
  if @config
84
80
  build_value
85
81
  else
86
- browser_strategy.csp_header
82
+ DEFAULT_CSP_HEADER
87
83
  end
88
84
  end
89
85
 
90
86
  private
91
87
 
92
- def browser_strategy
93
- @browser_strategy ||= BrowserStrategy.build(self)
94
- end
95
-
96
- def directives
97
- browser_strategy.directives
98
- end
99
-
100
88
  def build_value
101
- fill_directives unless disable_fill_missing?
102
- browser_strategy.add_missing_extension_values unless disable_chrome_extension?
89
+ raise "Expected to find default_src directive value" unless @config[:default_src]
103
90
  append_http_additions unless ssl_request?
104
-
105
91
  header_value = [
106
- build_impl_specific_directives,
92
+ # ensure default-src is first
93
+ build_directive(:default_src),
107
94
  generic_directives(@config),
108
95
  report_uri_directive,
109
96
  script_nonce_directive,
@@ -118,9 +105,8 @@ module SecureHeaders
118
105
 
119
106
  def fill_directives
120
107
  return unless @config[:default_src]
121
-
122
108
  default = @config[:default_src]
123
- directives.each do |directive|
109
+ DIRECTIVES.each do |directive|
124
110
  unless @config[directive]
125
111
  @config[directive] = default
126
112
  end
@@ -130,7 +116,6 @@ module SecureHeaders
130
116
 
131
117
  def append_http_additions
132
118
  return unless http_additions
133
-
134
119
  http_additions.each do |k, v|
135
120
  @config[k] ||= []
136
121
  @config[k] << v
@@ -146,14 +131,10 @@ module SecureHeaders
146
131
  end
147
132
  end
148
133
 
149
- def filter_unsupported_directives
150
- @config = browser_strategy.filter_unsupported_directives(@config)
151
- end
152
-
153
134
  # translates 'inline','self', 'none' and 'eval' to their respective impl-specific values.
154
135
  def translate_dir_value val
155
136
  if %w{inline eval}.include?(val)
156
- translate_inline_or_eval(val)
137
+ val == 'inline' ? "'unsafe-inline'" : "'unsafe-eval'"
157
138
  # self/none are special sources/src-dir-values and need to be quoted in chrome
158
139
  elsif %{self none}.include?(val)
159
140
  "'#{val}'"
@@ -162,33 +143,21 @@ module SecureHeaders
162
143
  end
163
144
  end
164
145
 
165
- def translate_inline_or_eval val
166
- browser_strategy.translate_inline_or_eval(val)
167
- end
168
-
169
146
  # if we have a forwarding endpoint setup and we are not on the same origin as our report_uri
170
147
  # or only a path was supplied (in which case we assume cross-host)
171
148
  # we need to forward the request for Firefox.
172
149
  def normalize_reporting_endpoint
173
- return unless browser_strategy.normalize_reporting_endpoint?
174
- if same_origin? || report_uri.nil? || URI.parse(report_uri).host.nil?
175
- return
176
- end
150
+ if @ua && @ua =~ /Firefox/
151
+ if same_origin? || report_uri.nil? || URI.parse(report_uri).host.nil?
152
+ return
153
+ end
177
154
 
178
- if forward_endpoint
179
- @report_uri = FF_CSP_ENDPOINT
155
+ if forward_endpoint
156
+ @report_uri = FF_CSP_ENDPOINT
157
+ end
180
158
  end
181
159
  end
182
160
 
183
- def build_impl_specific_directives
184
- default = expect_directive_value(:default_src)
185
- browser_strategy.build_impl_specific_directives(default)
186
- end
187
-
188
- def expect_directive_value key
189
- @config.delete(key) {|k| raise ContentSecurityPolicyBuildError.new("Expected to find #{k} directive value")}
190
- end
191
-
192
161
  def same_origin?
193
162
  return unless report_uri && request_uri
194
163
 
@@ -232,19 +201,24 @@ module SecureHeaders
232
201
  end
233
202
 
234
203
  config.keys.sort_by{|k| k.to_s}.each do |k| # ensure consistent ordering
235
- header_value += "#{symbol_to_hyphen_case(k)} #{config[k].join(" ")}; "
204
+ header_value += build_directive(k)
236
205
  end
237
206
 
238
207
  header_value
239
208
  end
240
209
 
210
+ # build and deletes the directive
211
+ def build_directive(key)
212
+ "#{symbol_to_hyphen_case(key)} #{@config.delete(key).join(" ")}; "
213
+ end
214
+
241
215
  def symbol_to_hyphen_case sym
242
216
  sym.to_s.gsub('_', '-')
243
217
  end
244
218
 
245
219
  def parse_request request
246
- @browser = Brwsr::Browser.new(:ua => request.env['HTTP_USER_AGENT'])
247
220
  @ssl_request = request.ssl?
221
+ @ua = request.env['HTTP_USER_AGENT']
248
222
  @request_uri = if request.respond_to?(:original_url)
249
223
  # rails 3.1+
250
224
  request.original_url
@@ -1,3 +1,3 @@
1
1
  module SecureHeaders
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -18,6 +18,5 @@ Gem::Specification.new do |gem|
18
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
20
  gem.require_paths = ["lib"]
21
- gem.add_dependency "brwsr", ">= 1.1.1"
22
21
  gem.add_development_dependency "rake"
23
22
  end
@@ -5,7 +5,7 @@ describe ContentSecurityPolicyController do
5
5
  {
6
6
  "csp-report" => {
7
7
  "document-uri" => "http://localhost:3001/csp","violated-directive" => "script-src 'none'",
8
- "original-policy" => "default-src https://* 'unsafe-eval'; frame-src 'self'; img-src chrome-extension: https://*; report-uri http://localhost:3001/scribes/csp_report; script-src 'none'; style-src 'unsafe-inline' 'self';",
8
+ "original-policy" => "default-src https://* 'unsafe-eval'; frame-src 'self'; img-src https://*; report-uri http://localhost:3001/scribes/csp_report; script-src 'none'; style-src 'unsafe-inline' 'self';",
9
9
  "blocked-uri" => "http://localhost:3001/stuff.js"
10
10
  }
11
11
  }
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'brwsr'
3
2
 
4
3
  module SecureHeaders
5
4
  describe ContentSecurityPolicy do
@@ -32,17 +31,17 @@ module SecureHeaders
32
31
  describe "#name" do
33
32
  context "when supplying options to override request" do
34
33
  specify { ContentSecurityPolicy.new(default_opts, :ua => IE).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
35
- specify { ContentSecurityPolicy.new(default_opts, :ua => FIREFOX).name.should == FIREFOX_CSP_HEADER_NAME + "-Report-Only"}
34
+ specify { ContentSecurityPolicy.new(default_opts, :ua => FIREFOX).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
36
35
  specify { ContentSecurityPolicy.new(default_opts, :ua => FIREFOX_23).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
37
- specify { ContentSecurityPolicy.new(default_opts, :ua => CHROME).name.should == WEBKIT_CSP_HEADER_NAME + "-Report-Only"}
36
+ specify { ContentSecurityPolicy.new(default_opts, :ua => CHROME).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
38
37
  specify { ContentSecurityPolicy.new(default_opts, :ua => CHROME_25).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
39
38
  end
40
39
 
41
40
  context "when in report-only mode" do
42
41
  specify { ContentSecurityPolicy.new(default_opts, :request => request_for(IE)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
43
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX)).name.should == FIREFOX_CSP_HEADER_NAME + "-Report-Only"}
42
+ specify { ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
44
43
  specify { ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX_23)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
45
- specify { ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME)).name.should == WEBKIT_CSP_HEADER_NAME + "-Report-Only"}
44
+ specify { ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
46
45
  specify { ContentSecurityPolicy.new(default_opts, :request => request_for(CHROME_25)).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
47
46
  end
48
47
 
@@ -50,18 +49,18 @@ module SecureHeaders
50
49
  let(:opts) { default_opts.merge(:enforce => true)}
51
50
 
52
51
  specify { ContentSecurityPolicy.new(opts, :request => request_for(IE)).name.should == STANDARD_HEADER_NAME}
53
- specify { ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX)).name.should == FIREFOX_CSP_HEADER_NAME}
52
+ specify { ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX)).name.should == STANDARD_HEADER_NAME}
54
53
  specify { ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX_23)).name.should == STANDARD_HEADER_NAME}
55
- specify { ContentSecurityPolicy.new(opts, :request => request_for(CHROME)).name.should == WEBKIT_CSP_HEADER_NAME}
54
+ specify { ContentSecurityPolicy.new(opts, :request => request_for(CHROME)).name.should == STANDARD_HEADER_NAME}
56
55
  specify { ContentSecurityPolicy.new(opts, :request => request_for(CHROME_25)).name.should == STANDARD_HEADER_NAME}
57
56
  end
58
57
 
59
58
  context "when in experimental mode" do
60
59
  let(:opts) { default_opts.merge(:enforce => true).merge(:experimental => {})}
61
60
  specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(IE)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
62
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX)}).name.should == FIREFOX_CSP_HEADER_NAME + "-Report-Only"}
61
+ specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
63
62
  specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(FIREFOX_23)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
64
- specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME)}).name.should == WEBKIT_CSP_HEADER_NAME + "-Report-Only"}
63
+ specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
65
64
  specify { ContentSecurityPolicy.new(opts, {:experimental => true, :request => request_for(CHROME_25)}).name.should == STANDARD_HEADER_NAME + "-Report-Only"}
66
65
  end
67
66
  end
@@ -74,43 +73,10 @@ module SecureHeaders
74
73
  @opts = default_opts
75
74
  end
76
75
 
77
- context "X-Content-Security-Policy" do
78
- it "converts the script values to their equivilents" do
79
- csp = ContentSecurityPolicy.new(@opts, :request => request_for(FIREFOX))
80
- csp.value.should include("script-src https://* data: 'self' 'none'")
81
- csp.value.should include('options inline-script eval-script')
82
- end
83
- end
84
-
85
- context "X-Webkit-CSP" do
76
+ context "Content-Security-Policy" do
86
77
  it "converts the script values to their equivilents" do
87
78
  csp = ContentSecurityPolicy.new(@opts, :request => request_for(CHROME))
88
- csp.value.should include("script-src 'unsafe-inline' 'unsafe-eval' https://* data: 'self' 'none' chrome-extension")
89
- end
90
- end
91
- end
92
-
93
- describe "#build_impl_specific_directives" do
94
- context "X-Content-Security-Policy" do
95
- it "moves script-src inline and eval values to the options directive" do
96
- opts = {
97
- :default_src => 'https://*',
98
- :script_src => "inline eval https://*"
99
- }
100
- csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX))
101
- browser_specific = csp.send :build_impl_specific_directives
102
- browser_specific.should include('options inline-script eval-script;')
103
- end
104
-
105
- it "does not move values from style-src into options" do
106
- opts = {
107
- :default_src => 'https://*',
108
- :style_src => "inline eval https://*"
109
- }
110
- csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX))
111
- browser_specific = csp.send :build_impl_specific_directives
112
- browser_specific.should_not include('inline-script')
113
- browser_specific.should_not include('eval-script')
79
+ csp.value.should include("script-src 'unsafe-inline' 'unsafe-eval' https://* data: 'self' 'none'")
114
80
  end
115
81
  end
116
82
  end
@@ -162,8 +128,6 @@ module SecureHeaders
162
128
  csp = ContentSecurityPolicy.new({:report_uri => 'https://example.com'}, :request => request_for(FIREFOX, "https://anotherexample.com"))
163
129
  csp.send(:same_origin?).should be_false
164
130
  end
165
-
166
-
167
131
  end
168
132
 
169
133
  describe "#normalize_reporting_endpoint" do
@@ -252,7 +216,7 @@ module SecureHeaders
252
216
  csp.value.should == value
253
217
  end
254
218
 
255
- it "sends the chrome csp header if an unknown browser is supplied" do
219
+ it "sends the standard csp header if an unknown browser is supplied" do
256
220
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(IE))
257
221
  csp.value.should match "default-src"
258
222
  end
@@ -260,30 +224,7 @@ module SecureHeaders
260
224
  context "Firefox" do
261
225
  it "builds a csp header for firefox" do
262
226
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX))
263
- 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;"
264
- end
265
-
266
- it "does not append chrome-extension to directives" do
267
- csp = ContentSecurityPolicy.new(default_opts.merge(:disable_chrome_extension => false), :request => request_for(FIREFOX))
268
- csp.value.should_not match "chrome-extension:"
269
- end
270
-
271
- it "copies connect-src values to xhr_src values" do
272
- opts = {
273
- :default_src => 'http://twitter.com',
274
- :connect_src => 'self http://*.localhost.com:*',
275
- :disable_chrome_extension => true,
276
- :disable_fill_missing => true
277
- }
278
- csp = ContentSecurityPolicy.new(opts, :request => request_for(FIREFOX))
279
- csp.value.should =~ /xhr-src 'self' http:/
280
- end
281
-
282
- context "Firefox >= 23" do
283
- it "builds a csp header for firefox" do
284
- csp = ContentSecurityPolicy.new(default_opts, :request => request_for(FIREFOX_23))
285
- 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;"
286
- end
227
+ 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;"
287
228
  end
288
229
  end
289
230
 
@@ -297,20 +238,6 @@ module SecureHeaders
297
238
  csp = ContentSecurityPolicy.new(@options_with_forwarding, :request => request_for(CHROME))
298
239
  csp.value.should =~ /report-uri #{@options_with_forwarding[:report_uri]};/
299
240
  end
300
-
301
- it "whitelists chrome_extensions by default" do
302
- opts = {
303
- :default_src => 'https://*',
304
- :report_uri => '/csp_report',
305
- :script_src => 'inline eval https://* data:',
306
- :style_src => "inline https://* chrome-extension: about:"
307
- }
308
-
309
- csp = ContentSecurityPolicy.new(opts, :request => request_for(CHROME))
310
-
311
- # ignore the report-uri directive
312
- csp.value.split(';')[0...-1].each{|directive| directive.should =~ /chrome-extension:/}
313
- end
314
241
  end
315
242
 
316
243
  context "when supplying a experimental values" do
@@ -324,7 +251,6 @@ module SecureHeaders
324
251
  }
325
252
  }}
326
253
 
327
- let(:header) {}
328
254
  it "returns the original value" do
329
255
  header = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
330
256
  header.value.should == "default-src 'self'; img-src data:; script-src https://*;"
@@ -384,21 +310,21 @@ module SecureHeaders
384
310
  # for comparison purposes, if not using the experimental header this would produce
385
311
  # "allow 'self'; script-src https://*" for https requests
386
312
  # and
387
- # "allow 'self; script-src https://* http://*" for http requests
313
+ # "allow 'self'; script-src https://* http://*" for http requests
388
314
 
389
315
  it "uses the value in the experimental block over SSL" do
390
316
  csp = ContentSecurityPolicy.new(options, :experimental => true, :request => request_for(FIREFOX, '/', :ssl => true))
391
- csp.value.should == "allow 'self'; img-src data:; script-src 'self';"
317
+ csp.value.should == "default-src 'self'; img-src data:; script-src 'self';"
392
318
  end
393
319
 
394
320
  it "detects the :ssl => true option" do
395
321
  csp = ContentSecurityPolicy.new(options, :experimental => true, :ua => FIREFOX, :ssl => true)
396
- csp.value.should == "allow 'self'; img-src data:; script-src 'self';"
322
+ csp.value.should == "default-src 'self'; img-src data:; script-src 'self';"
397
323
  end
398
324
 
399
325
  it "merges the values from experimental/http_additions when not over SSL" do
400
326
  csp = ContentSecurityPolicy.new(options, :experimental => true, :request => request_for(FIREFOX))
401
- csp.value.should == "allow 'self'; img-src data:; script-src 'self' https://mycdn.example.com;"
327
+ csp.value.should == "default-src 'self'; img-src data:; script-src 'self' https://mycdn.example.com;"
402
328
  end
403
329
  end
404
330
  end
@@ -415,11 +341,6 @@ module SecureHeaders
415
341
  csp.value.should match "script-nonce random;"
416
342
  end
417
343
 
418
- it "uses the value in the X-Content-Security-Policy" do
419
- csp = ContentSecurityPolicy.new(options, :request => request_for(FIREFOX))
420
- csp.value.should match "script-nonce random;"
421
- end
422
-
423
344
  it "runs a dynamic nonce generator" do
424
345
  options[:script_nonce] = lambda { 'something' }
425
346
  csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
@@ -92,15 +92,7 @@ describe SecureHeaders do
92
92
  USER_AGENTS.each do |name, useragent|
93
93
  it "sets all default headers for #{name} (smoke test)" do
94
94
  stub_user_agent(useragent)
95
- number_of_headers = case name
96
- when :ie, :chrome
97
- 5
98
- when :ios5, :safari5, :safari5_1
99
- 3 # csp breaks these browsers
100
- else
101
- 4
102
- end
103
-
95
+ number_of_headers = 5
104
96
  subject.should_receive(:set_header).exactly(number_of_headers).times # a request for a given header
105
97
  subject.set_csp_header
106
98
  subject.set_x_frame_options_header
@@ -139,18 +131,10 @@ describe SecureHeaders do
139
131
 
140
132
  it "does not set the CSP header if disabled" do
141
133
  stub_user_agent(USER_AGENTS[:chrome])
142
- should_not_assign_header(WEBKIT_CSP_HEADER_NAME)
134
+ should_not_assign_header(STANDARD_HEADER_NAME)
143
135
  subject.set_csp_header(options_for(:csp).merge(:csp => false))
144
136
  end
145
137
 
146
- # apparently iOS5 safari with CSP in enforce mode causes nothing to render
147
- # it has no effect in report-only mode (as in no report is sent)
148
- it "does not set CSP header if using ios5" do
149
- stub_user_agent(USER_AGENTS[:ios5])
150
- subject.should_not_receive(:set_header)
151
- subject.set_csp_header(options_for(:csp))
152
- end
153
-
154
138
  context "when disabled by configuration settings" do
155
139
  it "does not set any headers when disabled" do
156
140
  ::SecureHeaders::Configuration.configure do |config|
@@ -214,7 +198,7 @@ describe SecureHeaders do
214
198
  end
215
199
 
216
200
  describe "#set_x_content_type_options" do
217
- [:ie, :chrome].each do |useragent|
201
+ USER_AGENTS.each do |useragent|
218
202
  context "when using #{useragent}" do
219
203
  before(:each) do
220
204
  stub_user_agent(USER_AGENTS[useragent])
@@ -237,7 +221,7 @@ describe SecureHeaders do
237
221
  context "when using Firefox" do
238
222
  it "sets CSP headers" do
239
223
  stub_user_agent(USER_AGENTS[:firefox])
240
- should_assign_header(FIREFOX_CSP_HEADER_NAME + "-Report-Only", FIREFOX_CSP_HEADER)
224
+ should_assign_header(STANDARD_HEADER_NAME + "-Report-Only", DEFAULT_CSP_HEADER)
241
225
  subject.set_csp_header
242
226
  end
243
227
  end
@@ -245,7 +229,7 @@ describe SecureHeaders do
245
229
  context "when using Chrome" do
246
230
  it "sets default CSP header" do
247
231
  stub_user_agent(USER_AGENTS[:chrome])
248
- should_assign_header(WEBKIT_CSP_HEADER_NAME + "-Report-Only", WEBKIT_CSP_HEADER)
232
+ should_assign_header(STANDARD_HEADER_NAME + "-Report-Only", DEFAULT_CSP_HEADER)
249
233
  subject.set_csp_header
250
234
  end
251
235
  end
@@ -253,7 +237,7 @@ describe SecureHeaders do
253
237
  context "when using a browser besides chrome/firefox" do
254
238
  it "sets the CSP header" do
255
239
  stub_user_agent(USER_AGENTS[:opera])
256
- should_assign_header(WEBKIT_CSP_HEADER_NAME + "-Report-Only", WEBKIT_CSP_HEADER)
240
+ should_assign_header(STANDARD_HEADER_NAME + "-Report-Only", DEFAULT_CSP_HEADER)
257
241
  subject.set_csp_header
258
242
  end
259
243
  end
@@ -273,14 +257,14 @@ describe SecureHeaders do
273
257
 
274
258
  it "does not set the header in enforce mode if experimental is supplied, but enforce is disabled" do
275
259
  opts = @opts.merge(:enforce => false)
276
- should_assign_header(WEBKIT_CSP_HEADER_NAME + "-Report-Only", anything)
277
- should_not_assign_header(WEBKIT_CSP_HEADER_NAME)
260
+ should_assign_header(STANDARD_HEADER_NAME + "-Report-Only", anything)
261
+ should_not_assign_header(STANDARD_HEADER_NAME)
278
262
  subject.set_csp_header(opts)
279
263
  end
280
264
 
281
265
  it "sets a header in enforce mode as well as report-only mode" do
282
- should_assign_header(WEBKIT_CSP_HEADER_NAME, anything)
283
- should_assign_header(WEBKIT_CSP_HEADER_NAME + "-Report-Only", anything)
266
+ should_assign_header(STANDARD_HEADER_NAME, anything)
267
+ should_assign_header(STANDARD_HEADER_NAME + "-Report-Only", anything)
284
268
  subject.set_csp_header(@opts)
285
269
  end
286
270
  end
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: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-17 00:00:00.000000000 Z
12
+ date: 2013-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: brwsr
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: 1.1.1
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: 1.1.1
30
14
  - !ruby/object:Gem::Dependency
31
15
  name: rake
32
16
  requirement: !ruby/object:Gem::Requirement
@@ -150,10 +134,6 @@ files:
150
134
  - lib/secure_headers.rb
151
135
  - lib/secure_headers/header.rb
152
136
  - lib/secure_headers/headers/content_security_policy.rb
153
- - lib/secure_headers/headers/content_security_policy/browser_strategy.rb
154
- - lib/secure_headers/headers/content_security_policy/firefox_browser_strategy.rb
155
- - lib/secure_headers/headers/content_security_policy/ie_browser_strategy.rb
156
- - lib/secure_headers/headers/content_security_policy/standard_browser_strategy.rb
157
137
  - lib/secure_headers/headers/strict_transport_security.rb
158
138
  - lib/secure_headers/headers/x_content_type_options.rb
159
139
  - lib/secure_headers/headers/x_frame_options.rb
@@ -1,78 +0,0 @@
1
- require "forwardable"
2
-
3
- module SecureHeaders
4
- class ContentSecurityPolicy
5
- class BrowserStrategy
6
- extend Forwardable
7
-
8
- def_delegators :@content_security_policy, :browser, :experimental, :enforce, :config
9
-
10
- def self.build(content_security_policy)
11
- browser = content_security_policy.browser
12
- klass = if browser.ie?
13
- IeBrowserStrategy
14
- elsif browser.firefox?
15
- if browser.version.to_i >= 23
16
- StandardBrowserStrategy
17
- else
18
- FirefoxBrowserStrategy
19
- end
20
- else
21
- StandardBrowserStrategy
22
- end
23
-
24
- klass.new content_security_policy
25
- end
26
-
27
- def initialize(content_security_policy)
28
- @content_security_policy = content_security_policy
29
- end
30
-
31
- def base_name
32
- SecureHeaders::ContentSecurityPolicy::STANDARD_HEADER_NAME
33
- end
34
-
35
- def name
36
- base = base_name
37
- if !enforce || experimental
38
- base += "-Report-Only"
39
- end
40
- base
41
- end
42
-
43
- def csp_header
44
- SecureHeaders::ContentSecurityPolicy::WEBKIT_CSP_HEADER
45
- end
46
-
47
- def directives
48
- SecureHeaders::ContentSecurityPolicy::WEBKIT_DIRECTIVES
49
- end
50
-
51
- def filter_unsupported_directives(config)
52
- config = config.dup
53
- config.delete(:frame_ancestors)
54
- config
55
- end
56
-
57
- def translate_inline_or_eval val
58
- val == 'inline' ? "'unsafe-inline'" : "'unsafe-eval'"
59
- end
60
-
61
- def build_impl_specific_directives(default)
62
- if default.any?
63
- "default-src #{default.join(" ")}; "
64
- else
65
- ""
66
- end
67
- end
68
-
69
- def normalize_reporting_endpoint?
70
- # noop except for Firefox for now
71
- end
72
-
73
- def add_missing_extension_values
74
- # noop except for chrome for now
75
- end
76
- end
77
- end
78
- end
@@ -1,72 +0,0 @@
1
- module SecureHeaders
2
- class ContentSecurityPolicy
3
- class FirefoxBrowserStrategy < BrowserStrategy
4
- def base_name
5
- SecureHeaders::ContentSecurityPolicy::FIREFOX_CSP_HEADER_NAME
6
- end
7
-
8
- def csp_header
9
- SecureHeaders::ContentSecurityPolicy::FIREFOX_CSP_HEADER
10
- end
11
-
12
- def directives
13
- SecureHeaders::ContentSecurityPolicy::FIREFOX_DIRECTIVES
14
- end
15
-
16
- def filter_unsupported_directives(config)
17
- config = config.dup
18
- config[:xhr_src] = config.delete(:connect_src) if config[:connect_src]
19
- config
20
- end
21
-
22
- def translate_inline_or_eval val
23
- val == 'inline' ? 'inline-script' : 'eval-script'
24
- end
25
-
26
- def build_impl_specific_directives(default)
27
- build_firefox_specific_preamble(default) || ''
28
- end
29
-
30
- def build_firefox_specific_preamble(default_src_value)
31
- header_value = ''
32
- header_value += "allow #{default_src_value.join(" ")}; " if default_src_value.any?
33
-
34
- options_directive = build_options_directive
35
- header_value += "options #{options_directive.join(" ")}; " if options_directive.any?
36
- header_value
37
- end
38
-
39
- # moves inline/eval values from script-src to options
40
- # discards those values in the style-src directive
41
- def build_options_directive
42
- options_directive = []
43
- config.each do |directive, val|
44
- next if val.is_a?(String)
45
- new_val = []
46
- val.each do |token|
47
- if ['inline-script', 'eval-script'].include?(token)
48
- # Firefox does not support blocking inline styles ATM
49
- # https://bugzilla.mozilla.org/show_bug.cgi?id=763879
50
- unless directive?(directive, "style_src") || options_directive.include?(token)
51
- options_directive << token
52
- end
53
- else
54
- new_val << token
55
- end
56
- end
57
- config[directive] = new_val
58
- end
59
-
60
- options_directive
61
- end
62
-
63
- def directive? val, name
64
- val.to_s.casecmp(name) == 0
65
- end
66
-
67
- def normalize_reporting_endpoint?
68
- true
69
- end
70
- end
71
- end
72
- end
@@ -1,6 +0,0 @@
1
- module SecureHeaders
2
- class ContentSecurityPolicy
3
- class IeBrowserStrategy < BrowserStrategy
4
- end
5
- end
6
- end
@@ -1,22 +0,0 @@
1
- module SecureHeaders
2
- class ContentSecurityPolicy
3
- class StandardBrowserStrategy < BrowserStrategy
4
- def base_name
5
- if (browser.firefox? && browser.version.to_i >= 23) || (browser.chrome? && browser.version.to_i >= 25)
6
- SecureHeaders::ContentSecurityPolicy::STANDARD_HEADER_NAME
7
- else
8
- SecureHeaders::ContentSecurityPolicy::WEBKIT_CSP_HEADER_NAME
9
- end
10
- end
11
-
12
- def add_missing_extension_values
13
- directives.each do |directive|
14
- next unless config[directive]
15
- if !config[directive].include?('chrome-extension:')
16
- config[directive] << 'chrome-extension:'
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end