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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +1 -0
- data/Gemfile +2 -1
- data/README.md +56 -16
- data/Rakefile +2 -2
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/.rspec +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22}/Gemfile +2 -1
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/README.rdoc +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/Rakefile +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/application_controller.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/other_things_controller.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/controllers/things_controller.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/models/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/layouts/application.html.erb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/other_things/index.html.erb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/app/views/things/index.html.erb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config.ru +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/application.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/boot.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/environment.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/environments/test.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/initializers/secure_headers.rb +2 -3
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/routes.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/config/script_hashes.yml +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/lib/assets/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/lib/tasks/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12/vendor/assets/javascripts → rails_3_2_22/log}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/controllers/other_things_controller_spec.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/controllers/things_controller_spec.rb +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/spec_helper.rb +0 -0
- data/fixtures/{rails_3_2_12/vendor/assets/stylesheets → rails_3_2_22/vendor/assets/javascripts}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12/vendor/plugins → rails_3_2_22/vendor/assets/stylesheets}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init/app/models → rails_3_2_22/vendor/plugins}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/.rspec +0 -0
- data/fixtures/{rails_3_2_12 → rails_3_2_22_no_init}/Gemfile +2 -2
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/README.rdoc +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/Rakefile +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/application_controller.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/other_things_controller.rb +2 -2
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/things_controller.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init/lib/assets → rails_3_2_22_no_init/app/models}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/layouts/application.html.erb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/other_things/index.html.erb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/things/index.html.erb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config.ru +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/application.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/boot.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/environment.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/environments/test.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/config/routes.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init/lib/tasks → rails_3_2_22_no_init/lib/assets}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init/vendor/assets/javascripts → rails_3_2_22_no_init/lib/tasks}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init/vendor/assets/stylesheets → rails_3_2_22_no_init/log}/.gitkeep +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/controllers/other_things_controller_spec.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/controllers/things_controller_spec.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/spec/spec_helper.rb +0 -0
- data/fixtures/{rails_3_2_12_no_init/vendor/plugins → rails_3_2_22_no_init/vendor/assets/javascripts}/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/vendor/assets/stylesheets/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/vendor/plugins/.gitkeep +0 -0
- data/fixtures/rails_4_1_8/config/initializers/secure_headers.rb +2 -3
- data/lib/secure_headers/headers/content_security_policy.rb +7 -37
- data/lib/secure_headers/version.rb +1 -1
- data/spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb +2 -2
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +20 -42
- data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +1 -1
- data/spec/lib/secure_headers/headers/x_download_options_spec.rb +1 -1
- data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +1 -1
- data/spec/lib/secure_headers_spec.rb +3 -7
- data/spec/spec_helper.rb +4 -0
- metadata +57 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdc7e4cc47367102f2318244051b544e4bc5d611
|
4
|
+
data.tar.gz: f4bb9651462b15c056ab9720a0c079283e9c2462
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 888729b84ba1eb266c25c3bbc218c270f9e262bcbf490363a2daad6202803f4ba71a21f59c1a36e816a06c01ab8d28126ba81e05ae4f37ac36a53ee670af8420
|
7
|
+
data.tar.gz: 26640f0a917396faf083eaff557316d4a376e6956ae95915cfb5c815de3269a6ec5cb9a9f6a7684d871d8ff634dc586bb6a6a20dd79ece6cee034d5ec8f20648
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.3
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
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
|
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.
|
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/
|
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/
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/fixtures/{rails_3_2_12 → rails_3_2_22}/spec/controllers/other_things_controller_spec.rb
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/fixtures/{rails_3_2_12/vendor/plugins → rails_3_2_22/vendor/assets/stylesheets}/.gitkeep
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class OtherThingsController < ApplicationController
|
2
|
-
ensure_security_headers :csp => {:default_src => 'self'
|
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
|
data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/controllers/things_controller.rb
RENAMED
File without changes
|
File without changes
|
data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/layouts/application.html.erb
RENAMED
File without changes
|
data/fixtures/{rails_3_2_12_no_init → rails_3_2_22_no_init}/app/views/other_things/index.html.erb
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/fixtures/{rails_3_2_12_no_init/vendor/assets/stylesheets → rails_3_2_22_no_init/log}/.gitkeep
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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
|
-
|
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 :
|
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
|
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
|
@@ -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
|
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
|
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
|
-
:
|
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'
|
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'
|
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:
|
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
|
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
|
@@ -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.
|
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-
|
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/
|
57
|
-
- fixtures/
|
58
|
-
- fixtures/
|
59
|
-
- fixtures/
|
60
|
-
- fixtures/
|
61
|
-
- fixtures/
|
62
|
-
- fixtures/
|
63
|
-
- fixtures/
|
64
|
-
- fixtures/
|
65
|
-
- fixtures/
|
66
|
-
- fixtures/
|
67
|
-
- fixtures/
|
68
|
-
- fixtures/
|
69
|
-
- fixtures/
|
70
|
-
- fixtures/
|
71
|
-
- fixtures/
|
72
|
-
- fixtures/
|
73
|
-
- fixtures/
|
74
|
-
- fixtures/
|
75
|
-
- fixtures/
|
76
|
-
- fixtures/
|
77
|
-
- fixtures/
|
78
|
-
- fixtures/
|
79
|
-
- fixtures/
|
80
|
-
- fixtures/
|
81
|
-
- fixtures/
|
82
|
-
- fixtures/
|
83
|
-
- fixtures/
|
84
|
-
- fixtures/
|
85
|
-
- fixtures/
|
86
|
-
- fixtures/
|
87
|
-
- fixtures/
|
88
|
-
- fixtures/
|
89
|
-
- fixtures/
|
90
|
-
- fixtures/
|
91
|
-
- fixtures/
|
92
|
-
- fixtures/
|
93
|
-
- fixtures/
|
94
|
-
- fixtures/
|
95
|
-
- fixtures/
|
96
|
-
- fixtures/
|
97
|
-
- fixtures/
|
98
|
-
- fixtures/
|
99
|
-
- fixtures/
|
100
|
-
- fixtures/
|
101
|
-
- fixtures/
|
102
|
-
- fixtures/
|
103
|
-
- fixtures/
|
104
|
-
- fixtures/
|
105
|
-
- fixtures/
|
106
|
-
- fixtures/
|
107
|
-
- fixtures/
|
108
|
-
- fixtures/
|
109
|
-
- fixtures/
|
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.
|
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,
|