secure_headers 1.0.0 → 1.1.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/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