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.
- 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,
|