secure_headers 2.3.0 → 2.4.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.

Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +1 -0
  4. data/Gemfile +2 -1
  5. data/README.md +56 -16
  6. data/Rakefile +2 -2
  7. data/fixtures/{rails_3_2_12 → rails_3_2_22}/.rspec +0 -0
  8. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22}/Gemfile +2 -1
  9. data/fixtures/{rails_3_2_12 → rails_3_2_22}/README.rdoc +0 -0
  10. data/fixtures/{rails_3_2_12 → rails_3_2_22}/Rakefile +0 -0
  11. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/application_controller.rb +0 -0
  12. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/other_things_controller.rb +0 -0
  13. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/things_controller.rb +0 -0
  14. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/models/.gitkeep +0 -0
  15. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/layouts/application.html.erb +0 -0
  16. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/other_things/index.html.erb +0 -0
  17. data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/things/index.html.erb +0 -0
  18. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config.ru +0 -0
  19. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/application.rb +0 -0
  20. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/boot.rb +0 -0
  21. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/environment.rb +0 -0
  22. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/environments/test.rb +0 -0
  23. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/initializers/secure_headers.rb +2 -3
  24. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/routes.rb +0 -0
  25. data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/script_hashes.yml +0 -0
  26. data/fixtures/{rails_3_2_12 → rails_3_2_22}/lib/assets/.gitkeep +0 -0
  27. data/fixtures/{rails_3_2_12 → rails_3_2_22}/lib/tasks/.gitkeep +0 -0
  28. data/fixtures/{rails_3_2_12/vendor/assets/javascripts → rails_3_2_22/log}/.gitkeep +0 -0
  29. data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/controllers/other_things_controller_spec.rb +0 -0
  30. data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/controllers/things_controller_spec.rb +0 -0
  31. data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/spec_helper.rb +0 -0
  32. data/fixtures/{rails_3_2_12/vendor/assets/stylesheets → rails_3_2_22/vendor/assets/javascripts}/.gitkeep +0 -0
  33. data/fixtures/{rails_3_2_12/vendor/plugins → rails_3_2_22/vendor/assets/stylesheets}/.gitkeep +0 -0
  34. data/fixtures/{rails_3_2_12_no_init/app/models → rails_3_2_22/vendor/plugins}/.gitkeep +0 -0
  35. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/.rspec +0 -0
  36. data/fixtures/{rails_3_2_12 → rails_3_2_22_no_init}/Gemfile +2 -2
  37. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/README.rdoc +0 -0
  38. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/Rakefile +0 -0
  39. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/application_controller.rb +0 -0
  40. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/other_things_controller.rb +2 -2
  41. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/things_controller.rb +0 -0
  42. data/fixtures/{rails_3_2_12_no_init/lib/assets → rails_3_2_22_no_init/app/models}/.gitkeep +0 -0
  43. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/layouts/application.html.erb +0 -0
  44. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/other_things/index.html.erb +0 -0
  45. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/things/index.html.erb +0 -0
  46. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config.ru +0 -0
  47. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/application.rb +0 -0
  48. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/boot.rb +0 -0
  49. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/environment.rb +0 -0
  50. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/environments/test.rb +0 -0
  51. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/routes.rb +0 -0
  52. data/fixtures/{rails_3_2_12_no_init/lib/tasks → rails_3_2_22_no_init/lib/assets}/.gitkeep +0 -0
  53. data/fixtures/{rails_3_2_12_no_init/vendor/assets/javascripts → rails_3_2_22_no_init/lib/tasks}/.gitkeep +0 -0
  54. data/fixtures/{rails_3_2_12_no_init/vendor/assets/stylesheets → rails_3_2_22_no_init/log}/.gitkeep +0 -0
  55. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/controllers/other_things_controller_spec.rb +0 -0
  56. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/controllers/things_controller_spec.rb +0 -0
  57. data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/spec_helper.rb +0 -0
  58. data/fixtures/{rails_3_2_12_no_init/vendor/plugins → rails_3_2_22_no_init/vendor/assets/javascripts}/.gitkeep +0 -0
  59. data/fixtures/rails_3_2_22_no_init/vendor/assets/stylesheets/.gitkeep +0 -0
  60. data/fixtures/rails_3_2_22_no_init/vendor/plugins/.gitkeep +0 -0
  61. data/fixtures/rails_4_1_8/config/initializers/secure_headers.rb +2 -3
  62. data/lib/secure_headers/headers/content_security_policy.rb +7 -37
  63. data/lib/secure_headers/version.rb +1 -1
  64. data/spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb +2 -2
  65. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +20 -42
  66. data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +1 -1
  67. data/spec/lib/secure_headers/headers/x_download_options_spec.rb +1 -1
  68. data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +1 -1
  69. data/spec/lib/secure_headers_spec.rb +3 -7
  70. data/spec/spec_helper.rb +4 -0
  71. metadata +57 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ea3335e72b8eaea53c9fc03a77c008b73fc674c
4
- data.tar.gz: 4097b301e8e7f18174abda1c6412f9652cd4c39a
3
+ metadata.gz: bdc7e4cc47367102f2318244051b544e4bc5d611
4
+ data.tar.gz: f4bb9651462b15c056ab9720a0c079283e9c2462
5
5
  SHA512:
6
- metadata.gz: 53db0ad5f6d9e7a85bde9aa167a927e3bda91351ce2f57af0f505d1b6c0856ca50b295ad87e26c1b25fa0142a95d8ef8b11f12f562377e60a0b398454abdd5b9
7
- data.tar.gz: a6c3c2366fcf08ed3749f6c6e9146e2fbc33fb167a504404e195bd9813c709b0d497c2c2fc64f138a482a5fcc68eb4d212895761722ae0beed4b49ccea481e81
6
+ metadata.gz: 888729b84ba1eb266c25c3bbc218c270f9e262bcbf490363a2daad6202803f4ba71a21f59c1a36e816a06c01ab8d28126ba81e05ae4f37ac36a53ee670af8420
7
+ data.tar.gz: 26640f0a917396faf083eaff557316d4a376e6956ae95915cfb5c815de3269a6ec5cb9a9f6a7684d871d8ff634dc586bb6a6a20dd79ece6cee034d5ec8f20648
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.6
1
+ 2.2.3
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
+ - "2.2"
4
5
  - "2.1"
5
6
  - "2.0.0"
6
7
  - "1.9.3"
data/Gemfile CHANGED
@@ -3,7 +3,8 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem 'rails', '3.2.12'
6
+ gem 'test-unit', '~> 3.0'
7
+ gem 'rails', '3.2.22'
7
8
  gem 'sqlite3', :platforms => [:ruby, :mswin, :mingw]
8
9
  gem 'jdbc-sqlite3', :platforms => [:jruby]
9
10
  gem 'rspec-rails', '>= 3.1'
data/README.md CHANGED
@@ -8,7 +8,7 @@ The gem will automatically apply several headers that are related to security.
8
8
  - X-Content-Type-Options - [Prevent content type sniffing](http://msdn.microsoft.com/en-us/library/ie/gg622941\(v=vs.85\).aspx)
9
9
  - X-Download-Options - [Prevent file downloads opening](http://msdn.microsoft.com/en-us/library/ie/jj542450(v=vs.85).aspx)
10
10
  - X-Permitted-Cross-Domain-Policies - [Restrict Adobe Flash Player's access to data](https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html)
11
- - Public Key Pinning - Pin certificate fingerprints in the browser to prevent man-in-the-middle attacks due to compromised Certificate Authorites. [Public Key Pinnning Specification](https://tools.ietf.org/html/rfc7469)
11
+ - Public Key Pinning - Pin certificate fingerprints in the browser to prevent man-in-the-middle attacks due to compromised Certificate Authorities. [Public Key Pinnning Specification](https://tools.ietf.org/html/rfc7469)
12
12
 
13
13
  ## Usage
14
14
 
@@ -29,16 +29,12 @@ The following methods are going to be called, unless they are provided in a `ski
29
29
  * `:set_x_download_options_header`
30
30
  * `:set_x_permitted_cross_domain_policies_header`
31
31
 
32
- ### Bonus Features
33
-
34
- This gem makes a few assumptions about how you will use some features. For example:
35
-
36
- * 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.
37
-
38
32
  ## Configuration
39
33
 
40
34
  **Place the following in an initializer (recommended):**
41
35
 
36
+ **NOTE: All CSP config values accept procs for one way of dynamically setting values**
37
+
42
38
  ```ruby
43
39
  ::SecureHeaders::Configuration.configure do |config|
44
40
  config.hsts = {:max_age => 20.years.to_i, :include_subdomains => true}
@@ -48,10 +44,23 @@ This gem makes a few assumptions about how you will use some features. For exam
48
44
  config.x_download_options = 'noopen'
49
45
  config.x_permitted_cross_domain_policies = 'none'
50
46
  config.csp = {
51
- :default_src => "https: self",
52
- :enforce => proc {|controller| controller.current_user.enforce_csp? },
47
+ :default_src => "https: 'self'",
48
+ :enforce => proc {|controller| controller.my_feature_flag_api.enabled? },
53
49
  :frame_src => "https: http:.twimg.com http://itunes.apple.com",
54
50
  :img_src => "https:",
51
+ :connect_src => "wws:"
52
+ :font_src => "'self' data:",
53
+ :frame_src => "'self'",
54
+ :img_src => "mycdn.com data:",
55
+ :media_src => "utoob.com",
56
+ :object_src => "'self'",
57
+ :script_src => "'self'",
58
+ :style_src => "'unsafe-inline'",
59
+ :base_uri => "'self'",
60
+ :child_src => "'self'",
61
+ :form_action => "'self' github.com",
62
+ :frame_ancestors => "'none'",
63
+ :plugin_types => 'application/x-shockwave-flash',
55
64
  :report_uri => '//example.com/uri-directive'
56
65
  }
57
66
  config.hpkp = {
@@ -81,6 +90,37 @@ ensure_security_headers(
81
90
  )
82
91
  ```
83
92
 
93
+ ## Per-action configuration
94
+
95
+ Sometimes you need to override your content security policy for a given endpoint. Rather than applying the exception globally, you have a few options:
96
+
97
+ 1. Use procs as config values as mentioned above.
98
+ 1. Specifying `ensure_security_headers csp: ::SecureHeaders::Configuration.csp.merge(script_src: shadyhost.com)` in a descendent controller will override the settings for that controller only.
99
+ 1. Override the `secure_header_options_for` class instance method. e.g.
100
+
101
+ ```ruby
102
+ class SomethingController < ApplicationController
103
+ def wumbus
104
+ # gets style-src override
105
+ end
106
+
107
+ def diffendoofer
108
+ # does not get style-src override
109
+ end
110
+
111
+ def secure_header_options_for(header, options)
112
+ options = super
113
+ if params[:action] == "wumbus"
114
+ if header == :csp
115
+ options.merge(style_src: "'self'")
116
+ end
117
+ else
118
+ options
119
+ end
120
+ end
121
+ end
122
+ ```
123
+
84
124
  ## Options for ensure\_security\_headers
85
125
 
86
126
  **To disable any of these headers, supply a value of false (e.g. :hsts => false), supplying nil will set the default value**
@@ -142,7 +182,7 @@ This configuration will likely work for most applications without modification.
142
182
  ```ruby
143
183
  # most basic example
144
184
  :csp => {
145
- :default_src => "https: inline eval",
185
+ :default_src => "https: 'unsafe-inline' 'unsafe-eval'",
146
186
  :report_uri => '/uri-directive'
147
187
  }
148
188
 
@@ -158,7 +198,7 @@ This configuration will likely work for most applications without modification.
158
198
 
159
199
  # 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
160
200
  :csp => {
161
- :default_src => 'self',
201
+ :default_src => "'self'",
162
202
  :img_src => '*',
163
203
  :object_src => ['media1.com', 'media2.com', '*.cdn.com'],
164
204
  # alternatively (NOT csv) :object_src => 'media1.com media2.com *.cdn.com'
@@ -197,8 +237,8 @@ Setting a nonce will also set 'unsafe-inline' for browsers that don't support no
197
237
 
198
238
  ```ruby
199
239
  :csp => {
200
- :default_src => 'self',
201
- :script_src => 'self nonce'
240
+ :default_src => "'self'",
241
+ :script_src => "'self' nonce"
202
242
  }
203
243
  ```
204
244
 
@@ -244,7 +284,7 @@ If you only have a few hashes, you can hardcode them for the entire app:
244
284
  ```ruby
245
285
  config.csp = {
246
286
  :default_src => "https:",
247
- :script_src => 'self'
287
+ :script_src => "'self'"
248
288
  :script_hashes => ['sha1-abc', 'sha1-qwe']
249
289
  }
250
290
  ```
@@ -254,7 +294,7 @@ The following will work as well, but may not be as clear:
254
294
  ```ruby
255
295
  config.csp = {
256
296
  :default_src => "https:",
257
- :script_src => "self 'sha1-qwe'"
297
+ :script_src => "'self' 'sha1-qwe'"
258
298
  }
259
299
  ```
260
300
 
@@ -269,7 +309,7 @@ use ::SecureHeaders::ContentSecurityPolicy::ScriptHashMiddleware
269
309
  ```ruby
270
310
  config.csp = {
271
311
  :default_src => "https:",
272
- :script_src => 'self',
312
+ :script_src => "'self'",
273
313
  :script_hash_middleware => true
274
314
  }
275
315
  ```
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ task :default => :all_spec
15
15
  desc "Run all specs, and test fixture apps"
16
16
  task :all_spec => :spec do
17
17
  pwd = Dir.pwd
18
- Dir.chdir 'fixtures/rails_3_2_12'
18
+ Dir.chdir 'fixtures/rails_3_2_22'
19
19
  puts Dir.pwd
20
20
  str = `bundle install >> /dev/null; bundle exec rspec spec`
21
21
  puts str
@@ -25,7 +25,7 @@ task :all_spec => :spec do
25
25
  end
26
26
 
27
27
  Dir.chdir pwd
28
- Dir.chdir 'fixtures/rails_3_2_12_no_init'
28
+ Dir.chdir 'fixtures/rails_3_2_22_no_init'
29
29
  puts Dir.pwd
30
30
  puts `bundle install >> /dev/null; bundle exec rspec spec`
31
31
 
File without changes
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '3.2.12'
3
+ gem 'test-unit', '~> 3.0'
4
+ gem 'rails', '3.2.22'
4
5
  gem 'rspec-rails', '>= 2.0.0'
5
6
  gem 'secure_headers', :path => '../..'
File without changes
File without changes
File without changes
@@ -5,9 +5,8 @@
5
5
  config.x_xss_protection = {:value => 1, :mode => 'block'}
6
6
  config.x_permitted_cross_domain_policies = 'none'
7
7
  csp = {
8
- :default_src => "self",
9
- :script_src => "self nonce",
10
- :disable_fill_missing => true,
8
+ :default_src => "'self'",
9
+ :script_src => "'self' nonce",
11
10
  :report_uri => 'somewhere',
12
11
  :script_hash_middleware => true,
13
12
  :enforce => false # false means warnings only
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '3.2.12'
3
+ gem 'test-unit'
4
+ gem 'rails', '3.2.22'
4
5
  gem 'rspec-rails', '>= 2.0.0'
5
6
  gem 'secure_headers', :path => '../..'
6
-
@@ -1,5 +1,5 @@
1
1
  class OtherThingsController < ApplicationController
2
- ensure_security_headers :csp => {:default_src => 'self', :disable_fill_missing => true}
2
+ ensure_security_headers :csp => {:default_src => "'self'"}
3
3
  def index
4
4
 
5
5
  end
@@ -11,7 +11,7 @@ class OtherThingsController < ApplicationController
11
11
  def secure_header_options_for(header, options)
12
12
  if params[:action] == "other_action"
13
13
  if header == :csp
14
- options.merge(:style_src => 'self')
14
+ options.merge(:style_src => "'self'")
15
15
  end
16
16
  else
17
17
  options
@@ -5,9 +5,8 @@
5
5
  config.x_xss_protection = {:value => 0}
6
6
  config.x_permitted_cross_domain_policies = 'none'
7
7
  csp = {
8
- :default_src => "self",
9
- :script_src => "self nonce",
10
- :disable_fill_missing => true,
8
+ :default_src => "'self'",
9
+ :script_src => "'self' nonce",
11
10
  :report_uri => 'somewhere',
12
11
  :script_hash_middleware => true,
13
12
  :enforce => false # false means warnings only
@@ -20,33 +20,25 @@ module SecureHeaders
20
20
  :media_src,
21
21
  :object_src,
22
22
  :script_src,
23
- :style_src
24
- ]
25
-
26
- NON_DEFAULT_SOURCES = [
23
+ :style_src,
27
24
  :base_uri,
28
25
  :child_src,
29
26
  :form_action,
30
27
  :frame_ancestors,
31
- :plugin_types,
32
- :referrer,
33
- :reflected_xss
28
+ :plugin_types
34
29
  ]
35
30
 
36
31
  OTHER = [
37
32
  :report_uri
38
33
  ]
39
34
 
40
- SOURCE_DIRECTIVES = DIRECTIVES + NON_DEFAULT_SOURCES
41
-
42
- ALL_DIRECTIVES = DIRECTIVES + NON_DEFAULT_SOURCES + OTHER
35
+ ALL_DIRECTIVES = DIRECTIVES + OTHER
43
36
  CONFIG_KEY = :csp
44
37
  end
45
38
 
46
39
  include Constants
47
40
 
48
- attr_reader :disable_fill_missing, :ssl_request
49
- alias :disable_fill_missing? :disable_fill_missing
41
+ attr_reader :ssl_request
50
42
  alias :ssl_request? :ssl_request
51
43
 
52
44
  class << self
@@ -112,7 +104,7 @@ module SecureHeaders
112
104
  @config = config.inject({}) do |hash, (key, value)|
113
105
  config_val = value.respond_to?(:call) ? value.call(@controller) : value
114
106
 
115
- if SOURCE_DIRECTIVES.include?(key) # directives need to be normalized to arrays of strings
107
+ if DIRECTIVES.include?(key) # directives need to be normalized to arrays of strings
116
108
  config_val = config_val.split if config_val.is_a? String
117
109
  if config_val.is_a?(Array)
118
110
  config_val = config_val.map do |val|
@@ -128,15 +120,12 @@ module SecureHeaders
128
120
  @http_additions = @config.delete(:http_additions)
129
121
  @app_name = @config.delete(:app_name)
130
122
  @report_uri = @config.delete(:report_uri)
131
-
132
- @disable_fill_missing = !!@config.delete(:disable_fill_missing)
133
123
  @enforce = !!@config.delete(:enforce)
134
124
  @disable_img_src_data_uri = !!@config.delete(:disable_img_src_data_uri)
135
125
  @tag_report_uri = !!@config.delete(:tag_report_uri)
136
126
  @script_hashes = @config.delete(:script_hashes) || []
137
127
 
138
128
  add_script_hashes if @script_hashes.any?
139
- fill_directives unless disable_fill_missing?
140
129
  end
141
130
 
142
131
  ##
@@ -195,21 +184,10 @@ module SecureHeaders
195
184
  append_http_additions unless ssl_request?
196
185
  header_value = [
197
186
  generic_directives,
198
- non_default_directives,
199
187
  report_uri_directive
200
188
  ].join.strip
201
189
  end
202
190
 
203
- def fill_directives
204
- if default = @config[:default_src]
205
- DIRECTIVES.each do |directive|
206
- unless @config[directive]
207
- @config[directive] = default
208
- end
209
- end
210
- end
211
- end
212
-
213
191
  def append_http_additions
214
192
  return unless @http_additions
215
193
  @http_additions.each do |k, v|
@@ -220,9 +198,10 @@ module SecureHeaders
220
198
 
221
199
  def translate_dir_value val
222
200
  if %w{inline eval}.include?(val)
201
+ warn "[DEPRECATION] using inline/eval may not be supported in the future. Instead use 'unsafe-inline'/'unsafe-eval' instead."
223
202
  val == 'inline' ? "'unsafe-inline'" : "'unsafe-eval'"
224
- # self/none are special sources/src-dir-values and need to be quoted
225
203
  elsif %{self none}.include?(val)
204
+ warn "[DEPRECATION] using self/none may not be supported in the future. Instead use 'self'/'none' instead."
226
205
  "'#{val}'"
227
206
  elsif val == 'nonce'
228
207
  if supports_nonces?(@ua)
@@ -271,15 +250,6 @@ module SecureHeaders
271
250
  header_value
272
251
  end
273
252
 
274
- def non_default_directives
275
- header_value = ''
276
- NON_DEFAULT_SOURCES.each do |directive_name|
277
- header_value += build_directive(directive_name) if @config[directive_name]
278
- end
279
-
280
- header_value
281
- end
282
-
283
253
  def build_directive(key)
284
254
  "#{self.class.symbol_to_hyphen_case(key)} #{@config[key].join(" ")}; "
285
255
  end
@@ -1,3 +1,3 @@
1
1
  module SecureHeaders
2
- VERSION = "2.3.0"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -13,8 +13,8 @@ module SecureHeaders
13
13
  :disable_fill_missing => true,
14
14
  :default_src => 'https://*',
15
15
  :report_uri => '/csp_report',
16
- :script_src => 'inline eval https://* data:',
17
- :style_src => "inline https://* about:"
16
+ :script_src => "'unsafe-inline' 'unsafe-eval' https://* data:",
17
+ :style_src => "'unsafe-inline' https://* about:"
18
18
  }
19
19
  end
20
20
 
@@ -4,13 +4,13 @@ module SecureHeaders
4
4
  describe ContentSecurityPolicy do
5
5
  let(:default_opts) do
6
6
  {
7
- :disable_fill_missing => true,
8
7
  :default_src => 'https:',
9
8
  :report_uri => '/csp_report',
10
- :script_src => 'inline eval https: data:',
11
- :style_src => "inline https: about:"
9
+ :script_src => "'unsafe-inline' 'unsafe-eval' https: data:",
10
+ :style_src => "'unsafe-inline' https: about:"
12
11
  }
13
12
  end
13
+ let(:controller) { DummyClass.new }
14
14
 
15
15
  IE = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"
16
16
  FIREFOX = "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8"
@@ -67,7 +67,7 @@ module SecureHeaders
67
67
  json2 = %({"style-src":["'unsafe-inline'"],"img-src":["https:","data:"]})
68
68
  json3 = %({"style-src":["https:","about:"]})
69
69
  config = ContentSecurityPolicy.from_json(json1, json2, json3)
70
- policy = ContentSecurityPolicy.new(config.merge(:disable_fill_missing => true))
70
+ policy = ContentSecurityPolicy.new(config)
71
71
 
72
72
  expected = %({"default-src":["https:"],"script-src":["'unsafe-inline'","'unsafe-eval'","https:","data:"],"style-src":["'unsafe-inline'","https:","about:"],"img-src":["https:","data:"]})
73
73
  expect(policy.to_json).to eq(expected)
@@ -82,8 +82,7 @@ module SecureHeaders
82
82
 
83
83
  describe "#normalize_csp_options" do
84
84
  before(:each) do
85
- default_opts.delete(:disable_fill_missing)
86
- default_opts[:script_src] << ' self none'
85
+ default_opts[:script_src] << " 'self' 'none'"
87
86
  @opts = default_opts
88
87
  end
89
88
 
@@ -107,7 +106,7 @@ module SecureHeaders
107
106
 
108
107
  it "accepts procs for report-uris" do
109
108
  opts = {
110
- :default_src => 'self',
109
+ :default_src => "'self'",
111
110
  :report_uri => proc { "http://lambda/result" }
112
111
  }
113
112
 
@@ -119,7 +118,6 @@ module SecureHeaders
119
118
  opts = {
120
119
  :default_src => proc { "http://lambda/result" },
121
120
  :enforce => proc { true },
122
- :disable_fill_missing => proc { true }
123
121
  }
124
122
 
125
123
  csp = ContentSecurityPolicy.new(opts)
@@ -133,8 +131,7 @@ module SecureHeaders
133
131
 
134
132
  allow(controller).to receive(:current_user).and_return(user)
135
133
  opts = {
136
- :disable_fill_missing => true,
137
- :default_src => "self",
134
+ :default_src => "'self'",
138
135
  :enforce => lambda { |c| c.current_user.beta_testing? }
139
136
  }
140
137
  csp = ContentSecurityPolicy.new(opts, :controller => controller)
@@ -151,47 +148,28 @@ module SecureHeaders
151
148
  }.to raise_error(RuntimeError)
152
149
  end
153
150
 
154
- context "CSP level 2 directives" do
155
- let(:config) { {:default_src => 'self'} }
156
- ::SecureHeaders::ContentSecurityPolicy::Constants::NON_DEFAULT_SOURCES.each do |non_default_source|
157
- it "supports all level 2 directives" do
158
- directive_name = ::SecureHeaders::ContentSecurityPolicy.send(:symbol_to_hyphen_case, non_default_source)
159
- config.merge!({ non_default_source => "value" })
160
- csp = ContentSecurityPolicy.new(config, :request => request_for(CHROME))
161
- expect(csp.value).to match(/#{directive_name} value;/)
162
- end
163
- end
164
- end
165
-
166
151
  context "auto-whitelists data: uris for img-src" do
167
152
  it "sets the value if no img-src specified" do
168
- csp = ContentSecurityPolicy.new({:default_src => 'self', :disable_fill_missing => true}, :request => request_for(CHROME))
153
+ csp = ContentSecurityPolicy.new({:default_src => "'self'"}, :request => request_for(CHROME))
169
154
  expect(csp.value).to eq("default-src 'self'; img-src 'self' data:;")
170
155
  end
171
156
 
172
157
  it "appends the value if img-src is specified" do
173
- csp = ContentSecurityPolicy.new({:default_src => 'self', :img_src => 'self', :disable_fill_missing => true}, :request => request_for(CHROME))
158
+ csp = ContentSecurityPolicy.new({:default_src => "'self'", :img_src => "'self'"}, :request => request_for(CHROME))
174
159
  expect(csp.value).to eq("default-src 'self'; img-src 'self' data:;")
175
160
  end
176
161
 
177
162
  it "doesn't add a duplicate data uri if img-src specifies it already" do
178
- csp = ContentSecurityPolicy.new({:default_src => 'self', :img_src => 'self data:', :disable_fill_missing => true}, :request => request_for(CHROME))
163
+ csp = ContentSecurityPolicy.new({:default_src => "'self'", :img_src => "'self' data:"}, :request => request_for(CHROME))
179
164
  expect(csp.value).to eq("default-src 'self'; img-src 'self' data:;")
180
165
  end
181
166
 
182
167
  it "allows the user to disable img-src data: uris auto-whitelisting" do
183
- csp = ContentSecurityPolicy.new({:default_src => 'self', :img_src => 'self', :disable_img_src_data_uri => true, :disable_fill_missing => true}, :request => request_for(CHROME))
168
+ csp = ContentSecurityPolicy.new({:default_src => "'self'", :img_src => "'self'", :disable_img_src_data_uri => true}, :request => request_for(CHROME))
184
169
  expect(csp.value).to eq("default-src 'self'; img-src 'self';")
185
170
  end
186
171
  end
187
172
 
188
- it "fills in directives without values with default-src value" do
189
- options = default_opts.merge(:disable_fill_missing => false)
190
- csp = ContentSecurityPolicy.new(options, :request => request_for(CHROME))
191
- 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;"
192
- expect(csp.value).to eq(value)
193
- end
194
-
195
173
  it "sends the standard csp header if an unknown browser is supplied" do
196
174
  csp = ContentSecurityPolicy.new(default_opts, :request => request_for(IE))
197
175
  expect(csp.value).to match "default-src"
@@ -213,39 +191,39 @@ module SecureHeaders
213
191
 
214
192
  context "when using a nonce" do
215
193
  it "adds a nonce and unsafe-inline to the script-src value when using chrome" do
216
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(CHROME))
194
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce"), :request => request_for(CHROME), :controller => controller)
217
195
  expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
218
196
  end
219
197
 
220
198
  it "adds a nonce and unsafe-inline to the script-src value when using firefox" do
221
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(FIREFOX))
199
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce"), :request => request_for(FIREFOX), :controller => controller)
222
200
  expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
223
201
  end
224
202
 
225
203
  it "adds a nonce and unsafe-inline to the script-src value when using opera" do
226
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(OPERA))
204
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce"), :request => request_for(OPERA), :controller => controller)
227
205
  expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
228
206
  end
229
207
 
230
208
  it "does not add a nonce and unsafe-inline to the script-src value when using Safari" do
231
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(SAFARI))
209
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce"), :request => request_for(SAFARI), :controller => controller)
232
210
  expect(header.value).to include("script-src 'self' 'unsafe-inline'")
233
211
  expect(header.value).not_to include("nonce")
234
212
  end
235
213
 
236
214
  it "does not add a nonce and unsafe-inline to the script-src value when using IE" do
237
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce"), :request => request_for(IE))
215
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce"), :request => request_for(IE), :controller => controller)
238
216
  expect(header.value).to include("script-src 'self' 'unsafe-inline'")
239
217
  expect(header.value).not_to include("nonce")
240
218
  end
241
219
 
242
220
  it "adds a nonce and unsafe-inline to the style-src value" do
243
- header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "self nonce"), :request => request_for(CHROME))
221
+ header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "'self' nonce"), :request => request_for(CHROME), :controller => controller)
244
222
  expect(header.value).to include("style-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline'")
245
223
  end
246
224
 
247
225
  it "adds an identical nonce to the style and script-src directives" do
248
- header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "self nonce", :script_src => "self nonce"), :request => request_for(CHROME))
226
+ header = ContentSecurityPolicy.new(default_opts.merge(:style_src => "'self' nonce", :script_src => "'self' nonce"), :request => request_for(CHROME), :controller => controller)
249
227
  nonce = header.nonce
250
228
  value = header.value
251
229
  expect(value).to include("style-src 'self' 'nonce-#{nonce}' 'unsafe-inline'")
@@ -253,7 +231,7 @@ module SecureHeaders
253
231
  end
254
232
 
255
233
  it "does not add 'unsafe-inline' twice" do
256
- header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "self nonce inline"), :request => request_for(CHROME))
234
+ header = ContentSecurityPolicy.new(default_opts.merge(:script_src => "'self' nonce 'unsafe-inline'"), :request => request_for(CHROME), :controller => controller)
257
235
  expect(header.value).to include("script-src 'self' 'nonce-#{header.nonce}' 'unsafe-inline';")
258
236
  end
259
237
  end
@@ -301,7 +279,7 @@ module SecureHeaders
301
279
 
302
280
  describe ".add_to_env" do
303
281
  let(:controller) { double }
304
- let(:config) { {:default_src => 'self'} }
282
+ let(:config) { {:default_src => "'self'"} }
305
283
  let(:options) { {:controller => controller} }
306
284
 
307
285
  it "adds metadata to env" do
@@ -27,7 +27,7 @@ module SecureHeaders
27
27
  it "doesn't accept anything besides no-sniff" do
28
28
  expect {
29
29
  XContentTypeOptions.new("donkey")
30
- }.to raise_error
30
+ }.to raise_error(XContentTypeOptionsBuildError)
31
31
  end
32
32
  end
33
33
  end
@@ -25,7 +25,7 @@ module SecureHeaders
25
25
  it "doesn't accept anything besides noopen" do
26
26
  expect {
27
27
  XDownloadOptions.new("open")
28
- }.to raise_error
28
+ }.to raise_error(XDOBuildError)
29
29
  end
30
30
  end
31
31
  end
@@ -57,7 +57,7 @@ module SecureHeaders
57
57
  it "doesn't accept invalid values" do
58
58
  expect {
59
59
  XPermittedCrossDomainPolicies.new("open")
60
- }.to raise_error
60
+ }.to raise_error(XPCDPBuildError)
61
61
  end
62
62
  end
63
63
  end
@@ -1,10 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SecureHeaders do
4
- class DummyClass
5
- include ::SecureHeaders
6
- end
7
-
8
4
  subject {DummyClass.new}
9
5
  let(:headers) {double}
10
6
  let(:response) {double(:headers => headers)}
@@ -131,7 +127,7 @@ describe SecureHeaders do
131
127
 
132
128
  it "saves the options to the env when using script hashes" do
133
129
  opts = {
134
- :default_src => 'self',
130
+ :default_src => "'self'",
135
131
  :script_hash_middleware => true
136
132
  }
137
133
  stub_user_agent(USER_AGENTS[:chrome])
@@ -170,7 +166,7 @@ describe SecureHeaders do
170
166
  end
171
167
 
172
168
  it "produces a hash of headers given a hash as config" do
173
- hash = SecureHeaders::header_hash(:csp => {:default_src => 'none', :img_src => "data:", :disable_fill_missing => true})
169
+ hash = SecureHeaders::header_hash(:csp => {:default_src => "'none'", :img_src => "data:", :disable_fill_missing => true})
174
170
  expect(hash['Content-Security-Policy-Report-Only']).to eq("default-src 'none'; img-src data:;")
175
171
  expect_default_values(hash)
176
172
  end
@@ -190,7 +186,7 @@ describe SecureHeaders do
190
186
  }
191
187
  end
192
188
 
193
- hash = SecureHeaders::header_hash(:csp => {:default_src => 'none', :img_src => "data:", :disable_fill_missing => true})
189
+ hash = SecureHeaders::header_hash(:csp => {:default_src => "'none'", :img_src => "data:", :disable_fill_missing => true})
194
190
  ::SecureHeaders::Configuration.configure do |config|
195
191
  config.hsts = nil
196
192
  config.hpkp = nil
data/spec/spec_helper.rb CHANGED
@@ -31,6 +31,10 @@ USER_AGENTS = {
31
31
  :safari6 => "Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/536.30.1 (KHTML like Gecko) Version/6.0.5 Safari/536.30.1"
32
32
  }
33
33
 
34
+ class DummyClass
35
+ include ::SecureHeaders
36
+ end
37
+
34
38
  def should_assign_header name, value
35
39
  expect(response.headers).to receive(:[]=).with(name, value)
36
40
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secure_headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil Matatall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-30 00:00:00.000000000 Z
11
+ date: 2015-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -53,60 +53,60 @@ files:
53
53
  - LICENSE
54
54
  - README.md
55
55
  - Rakefile
56
- - fixtures/rails_3_2_12/.rspec
57
- - fixtures/rails_3_2_12/Gemfile
58
- - fixtures/rails_3_2_12/README.rdoc
59
- - fixtures/rails_3_2_12/Rakefile
60
- - fixtures/rails_3_2_12/app/controllers/application_controller.rb
61
- - fixtures/rails_3_2_12/app/controllers/other_things_controller.rb
62
- - fixtures/rails_3_2_12/app/controllers/things_controller.rb
63
- - fixtures/rails_3_2_12/app/models/.gitkeep
64
- - fixtures/rails_3_2_12/app/views/layouts/application.html.erb
65
- - fixtures/rails_3_2_12/app/views/other_things/index.html.erb
66
- - fixtures/rails_3_2_12/app/views/things/index.html.erb
67
- - fixtures/rails_3_2_12/config.ru
68
- - fixtures/rails_3_2_12/config/application.rb
69
- - fixtures/rails_3_2_12/config/boot.rb
70
- - fixtures/rails_3_2_12/config/environment.rb
71
- - fixtures/rails_3_2_12/config/environments/test.rb
72
- - fixtures/rails_3_2_12/config/initializers/secure_headers.rb
73
- - fixtures/rails_3_2_12/config/routes.rb
74
- - fixtures/rails_3_2_12/config/script_hashes.yml
75
- - fixtures/rails_3_2_12/lib/assets/.gitkeep
76
- - fixtures/rails_3_2_12/lib/tasks/.gitkeep
77
- - fixtures/rails_3_2_12/log/.gitkeep
78
- - fixtures/rails_3_2_12/spec/controllers/other_things_controller_spec.rb
79
- - fixtures/rails_3_2_12/spec/controllers/things_controller_spec.rb
80
- - fixtures/rails_3_2_12/spec/spec_helper.rb
81
- - fixtures/rails_3_2_12/vendor/assets/javascripts/.gitkeep
82
- - fixtures/rails_3_2_12/vendor/assets/stylesheets/.gitkeep
83
- - fixtures/rails_3_2_12/vendor/plugins/.gitkeep
84
- - fixtures/rails_3_2_12_no_init/.rspec
85
- - fixtures/rails_3_2_12_no_init/Gemfile
86
- - fixtures/rails_3_2_12_no_init/README.rdoc
87
- - fixtures/rails_3_2_12_no_init/Rakefile
88
- - fixtures/rails_3_2_12_no_init/app/controllers/application_controller.rb
89
- - fixtures/rails_3_2_12_no_init/app/controllers/other_things_controller.rb
90
- - fixtures/rails_3_2_12_no_init/app/controllers/things_controller.rb
91
- - fixtures/rails_3_2_12_no_init/app/models/.gitkeep
92
- - fixtures/rails_3_2_12_no_init/app/views/layouts/application.html.erb
93
- - fixtures/rails_3_2_12_no_init/app/views/other_things/index.html.erb
94
- - fixtures/rails_3_2_12_no_init/app/views/things/index.html.erb
95
- - fixtures/rails_3_2_12_no_init/config.ru
96
- - fixtures/rails_3_2_12_no_init/config/application.rb
97
- - fixtures/rails_3_2_12_no_init/config/boot.rb
98
- - fixtures/rails_3_2_12_no_init/config/environment.rb
99
- - fixtures/rails_3_2_12_no_init/config/environments/test.rb
100
- - fixtures/rails_3_2_12_no_init/config/routes.rb
101
- - fixtures/rails_3_2_12_no_init/lib/assets/.gitkeep
102
- - fixtures/rails_3_2_12_no_init/lib/tasks/.gitkeep
103
- - fixtures/rails_3_2_12_no_init/log/.gitkeep
104
- - fixtures/rails_3_2_12_no_init/spec/controllers/other_things_controller_spec.rb
105
- - fixtures/rails_3_2_12_no_init/spec/controllers/things_controller_spec.rb
106
- - fixtures/rails_3_2_12_no_init/spec/spec_helper.rb
107
- - fixtures/rails_3_2_12_no_init/vendor/assets/javascripts/.gitkeep
108
- - fixtures/rails_3_2_12_no_init/vendor/assets/stylesheets/.gitkeep
109
- - fixtures/rails_3_2_12_no_init/vendor/plugins/.gitkeep
56
+ - fixtures/rails_3_2_22/.rspec
57
+ - fixtures/rails_3_2_22/Gemfile
58
+ - fixtures/rails_3_2_22/README.rdoc
59
+ - fixtures/rails_3_2_22/Rakefile
60
+ - fixtures/rails_3_2_22/app/controllers/application_controller.rb
61
+ - fixtures/rails_3_2_22/app/controllers/other_things_controller.rb
62
+ - fixtures/rails_3_2_22/app/controllers/things_controller.rb
63
+ - fixtures/rails_3_2_22/app/models/.gitkeep
64
+ - fixtures/rails_3_2_22/app/views/layouts/application.html.erb
65
+ - fixtures/rails_3_2_22/app/views/other_things/index.html.erb
66
+ - fixtures/rails_3_2_22/app/views/things/index.html.erb
67
+ - fixtures/rails_3_2_22/config.ru
68
+ - fixtures/rails_3_2_22/config/application.rb
69
+ - fixtures/rails_3_2_22/config/boot.rb
70
+ - fixtures/rails_3_2_22/config/environment.rb
71
+ - fixtures/rails_3_2_22/config/environments/test.rb
72
+ - fixtures/rails_3_2_22/config/initializers/secure_headers.rb
73
+ - fixtures/rails_3_2_22/config/routes.rb
74
+ - fixtures/rails_3_2_22/config/script_hashes.yml
75
+ - fixtures/rails_3_2_22/lib/assets/.gitkeep
76
+ - fixtures/rails_3_2_22/lib/tasks/.gitkeep
77
+ - fixtures/rails_3_2_22/log/.gitkeep
78
+ - fixtures/rails_3_2_22/spec/controllers/other_things_controller_spec.rb
79
+ - fixtures/rails_3_2_22/spec/controllers/things_controller_spec.rb
80
+ - fixtures/rails_3_2_22/spec/spec_helper.rb
81
+ - fixtures/rails_3_2_22/vendor/assets/javascripts/.gitkeep
82
+ - fixtures/rails_3_2_22/vendor/assets/stylesheets/.gitkeep
83
+ - fixtures/rails_3_2_22/vendor/plugins/.gitkeep
84
+ - fixtures/rails_3_2_22_no_init/.rspec
85
+ - fixtures/rails_3_2_22_no_init/Gemfile
86
+ - fixtures/rails_3_2_22_no_init/README.rdoc
87
+ - fixtures/rails_3_2_22_no_init/Rakefile
88
+ - fixtures/rails_3_2_22_no_init/app/controllers/application_controller.rb
89
+ - fixtures/rails_3_2_22_no_init/app/controllers/other_things_controller.rb
90
+ - fixtures/rails_3_2_22_no_init/app/controllers/things_controller.rb
91
+ - fixtures/rails_3_2_22_no_init/app/models/.gitkeep
92
+ - fixtures/rails_3_2_22_no_init/app/views/layouts/application.html.erb
93
+ - fixtures/rails_3_2_22_no_init/app/views/other_things/index.html.erb
94
+ - fixtures/rails_3_2_22_no_init/app/views/things/index.html.erb
95
+ - fixtures/rails_3_2_22_no_init/config.ru
96
+ - fixtures/rails_3_2_22_no_init/config/application.rb
97
+ - fixtures/rails_3_2_22_no_init/config/boot.rb
98
+ - fixtures/rails_3_2_22_no_init/config/environment.rb
99
+ - fixtures/rails_3_2_22_no_init/config/environments/test.rb
100
+ - fixtures/rails_3_2_22_no_init/config/routes.rb
101
+ - fixtures/rails_3_2_22_no_init/lib/assets/.gitkeep
102
+ - fixtures/rails_3_2_22_no_init/lib/tasks/.gitkeep
103
+ - fixtures/rails_3_2_22_no_init/log/.gitkeep
104
+ - fixtures/rails_3_2_22_no_init/spec/controllers/other_things_controller_spec.rb
105
+ - fixtures/rails_3_2_22_no_init/spec/controllers/things_controller_spec.rb
106
+ - fixtures/rails_3_2_22_no_init/spec/spec_helper.rb
107
+ - fixtures/rails_3_2_22_no_init/vendor/assets/javascripts/.gitkeep
108
+ - fixtures/rails_3_2_22_no_init/vendor/assets/stylesheets/.gitkeep
109
+ - fixtures/rails_3_2_22_no_init/vendor/plugins/.gitkeep
110
110
  - fixtures/rails_4_1_8/Gemfile
111
111
  - fixtures/rails_4_1_8/README.rdoc
112
112
  - fixtures/rails_4_1_8/Rakefile
@@ -186,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  version: '0'
187
187
  requirements: []
188
188
  rubyforge_project:
189
- rubygems_version: 2.4.8
189
+ rubygems_version: 2.4.5.1
190
190
  signing_key:
191
191
  specification_version: 4
192
192
  summary: Add easily configured security headers to responses including content-security-policy,