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