secure_headers 2.5.3 → 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of secure_headers might be problematic. Click here for more details.

Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +2 -1
  4. data/Gemfile +9 -16
  5. data/README.md +154 -331
  6. data/Rakefile +2 -36
  7. data/lib/secure_headers/configuration.rb +189 -0
  8. data/lib/secure_headers/headers/content_security_policy.rb +341 -254
  9. data/lib/secure_headers/headers/public_key_pins.rb +43 -58
  10. data/lib/secure_headers/headers/strict_transport_security.rb +21 -49
  11. data/lib/secure_headers/headers/x_content_type_options.rb +18 -33
  12. data/lib/secure_headers/headers/x_download_options.rb +18 -33
  13. data/lib/secure_headers/headers/x_frame_options.rb +24 -34
  14. data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +19 -34
  15. data/lib/secure_headers/headers/x_xss_protection.rb +17 -48
  16. data/lib/secure_headers/middleware.rb +15 -0
  17. data/lib/secure_headers/padrino.rb +1 -2
  18. data/lib/secure_headers/railtie.rb +9 -6
  19. data/lib/secure_headers/view_helper.rb +27 -43
  20. data/lib/secure_headers.rb +254 -61
  21. data/secure_headers.gemspec +7 -12
  22. data/spec/lib/secure_headers/configuration_spec.rb +80 -0
  23. data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +111 -276
  24. data/spec/lib/secure_headers/headers/public_key_pins_spec.rb +17 -17
  25. data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +11 -43
  26. data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +11 -18
  27. data/spec/lib/secure_headers/headers/x_download_options_spec.rb +13 -17
  28. data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +15 -17
  29. data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +22 -39
  30. data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +20 -30
  31. data/spec/lib/secure_headers/middleware_spec.rb +40 -0
  32. data/spec/lib/secure_headers_spec.rb +201 -339
  33. data/spec/spec_helper.rb +30 -30
  34. data/upgrading-to-3-0.md +35 -0
  35. metadata +14 -100
  36. data/fixtures/rails_3_2_22/.rspec +0 -1
  37. data/fixtures/rails_3_2_22/Gemfile +0 -6
  38. data/fixtures/rails_3_2_22/README.rdoc +0 -261
  39. data/fixtures/rails_3_2_22/Rakefile +0 -7
  40. data/fixtures/rails_3_2_22/app/controllers/application_controller.rb +0 -4
  41. data/fixtures/rails_3_2_22/app/controllers/other_things_controller.rb +0 -5
  42. data/fixtures/rails_3_2_22/app/controllers/things_controller.rb +0 -5
  43. data/fixtures/rails_3_2_22/app/models/.gitkeep +0 -0
  44. data/fixtures/rails_3_2_22/app/views/layouts/application.html.erb +0 -11
  45. data/fixtures/rails_3_2_22/app/views/other_things/index.html.erb +0 -2
  46. data/fixtures/rails_3_2_22/app/views/things/index.html.erb +0 -1
  47. data/fixtures/rails_3_2_22/config/application.rb +0 -14
  48. data/fixtures/rails_3_2_22/config/boot.rb +0 -6
  49. data/fixtures/rails_3_2_22/config/environment.rb +0 -5
  50. data/fixtures/rails_3_2_22/config/environments/test.rb +0 -37
  51. data/fixtures/rails_3_2_22/config/initializers/secure_headers.rb +0 -16
  52. data/fixtures/rails_3_2_22/config/routes.rb +0 -4
  53. data/fixtures/rails_3_2_22/config/script_hashes.yml +0 -5
  54. data/fixtures/rails_3_2_22/config.ru +0 -7
  55. data/fixtures/rails_3_2_22/lib/assets/.gitkeep +0 -0
  56. data/fixtures/rails_3_2_22/lib/tasks/.gitkeep +0 -0
  57. data/fixtures/rails_3_2_22/log/.gitkeep +0 -0
  58. data/fixtures/rails_3_2_22/spec/controllers/other_things_controller_spec.rb +0 -83
  59. data/fixtures/rails_3_2_22/spec/controllers/things_controller_spec.rb +0 -54
  60. data/fixtures/rails_3_2_22/spec/spec_helper.rb +0 -15
  61. data/fixtures/rails_3_2_22/vendor/assets/javascripts/.gitkeep +0 -0
  62. data/fixtures/rails_3_2_22/vendor/assets/stylesheets/.gitkeep +0 -0
  63. data/fixtures/rails_3_2_22/vendor/plugins/.gitkeep +0 -0
  64. data/fixtures/rails_3_2_22_no_init/.rspec +0 -1
  65. data/fixtures/rails_3_2_22_no_init/Gemfile +0 -6
  66. data/fixtures/rails_3_2_22_no_init/README.rdoc +0 -261
  67. data/fixtures/rails_3_2_22_no_init/Rakefile +0 -7
  68. data/fixtures/rails_3_2_22_no_init/app/controllers/application_controller.rb +0 -4
  69. data/fixtures/rails_3_2_22_no_init/app/controllers/other_things_controller.rb +0 -20
  70. data/fixtures/rails_3_2_22_no_init/app/controllers/things_controller.rb +0 -5
  71. data/fixtures/rails_3_2_22_no_init/app/models/.gitkeep +0 -0
  72. data/fixtures/rails_3_2_22_no_init/app/views/layouts/application.html.erb +0 -12
  73. data/fixtures/rails_3_2_22_no_init/app/views/other_things/index.html.erb +0 -1
  74. data/fixtures/rails_3_2_22_no_init/app/views/things/index.html.erb +0 -0
  75. data/fixtures/rails_3_2_22_no_init/config/application.rb +0 -17
  76. data/fixtures/rails_3_2_22_no_init/config/boot.rb +0 -6
  77. data/fixtures/rails_3_2_22_no_init/config/environment.rb +0 -5
  78. data/fixtures/rails_3_2_22_no_init/config/environments/test.rb +0 -37
  79. data/fixtures/rails_3_2_22_no_init/config/routes.rb +0 -4
  80. data/fixtures/rails_3_2_22_no_init/config.ru +0 -4
  81. data/fixtures/rails_3_2_22_no_init/lib/assets/.gitkeep +0 -0
  82. data/fixtures/rails_3_2_22_no_init/lib/tasks/.gitkeep +0 -0
  83. data/fixtures/rails_3_2_22_no_init/log/.gitkeep +0 -0
  84. data/fixtures/rails_3_2_22_no_init/spec/controllers/other_things_controller_spec.rb +0 -56
  85. data/fixtures/rails_3_2_22_no_init/spec/controllers/things_controller_spec.rb +0 -54
  86. data/fixtures/rails_3_2_22_no_init/spec/spec_helper.rb +0 -5
  87. data/fixtures/rails_3_2_22_no_init/vendor/assets/javascripts/.gitkeep +0 -0
  88. data/fixtures/rails_3_2_22_no_init/vendor/assets/stylesheets/.gitkeep +0 -0
  89. data/fixtures/rails_3_2_22_no_init/vendor/plugins/.gitkeep +0 -0
  90. data/fixtures/rails_4_1_8/Gemfile +0 -5
  91. data/fixtures/rails_4_1_8/README.rdoc +0 -28
  92. data/fixtures/rails_4_1_8/Rakefile +0 -6
  93. data/fixtures/rails_4_1_8/app/controllers/application_controller.rb +0 -4
  94. data/fixtures/rails_4_1_8/app/controllers/concerns/.keep +0 -0
  95. data/fixtures/rails_4_1_8/app/controllers/other_things_controller.rb +0 -5
  96. data/fixtures/rails_4_1_8/app/controllers/things_controller.rb +0 -5
  97. data/fixtures/rails_4_1_8/app/models/.keep +0 -0
  98. data/fixtures/rails_4_1_8/app/models/concerns/.keep +0 -0
  99. data/fixtures/rails_4_1_8/app/views/layouts/application.html.erb +0 -11
  100. data/fixtures/rails_4_1_8/app/views/other_things/index.html.erb +0 -2
  101. data/fixtures/rails_4_1_8/app/views/things/index.html.erb +0 -1
  102. data/fixtures/rails_4_1_8/config/application.rb +0 -15
  103. data/fixtures/rails_4_1_8/config/boot.rb +0 -4
  104. data/fixtures/rails_4_1_8/config/environment.rb +0 -5
  105. data/fixtures/rails_4_1_8/config/environments/test.rb +0 -10
  106. data/fixtures/rails_4_1_8/config/initializers/secure_headers.rb +0 -16
  107. data/fixtures/rails_4_1_8/config/routes.rb +0 -4
  108. data/fixtures/rails_4_1_8/config/script_hashes.yml +0 -5
  109. data/fixtures/rails_4_1_8/config/secrets.yml +0 -22
  110. data/fixtures/rails_4_1_8/config.ru +0 -4
  111. data/fixtures/rails_4_1_8/lib/assets/.keep +0 -0
  112. data/fixtures/rails_4_1_8/lib/tasks/.keep +0 -0
  113. data/fixtures/rails_4_1_8/log/.keep +0 -0
  114. data/fixtures/rails_4_1_8/spec/controllers/other_things_controller_spec.rb +0 -83
  115. data/fixtures/rails_4_1_8/spec/controllers/things_controller_spec.rb +0 -59
  116. data/fixtures/rails_4_1_8/spec/spec_helper.rb +0 -15
  117. data/fixtures/rails_4_1_8/vendor/assets/javascripts/.keep +0 -0
  118. data/fixtures/rails_4_1_8/vendor/assets/stylesheets/.keep +0 -0
  119. data/lib/secure_headers/controller_extension.rb +0 -158
  120. data/lib/secure_headers/hash_helper.rb +0 -7
  121. data/lib/secure_headers/header.rb +0 -5
  122. data/lib/secure_headers/headers/content_security_policy/script_hash_middleware.rb +0 -22
  123. data/lib/secure_headers/version.rb +0 -3
  124. data/lib/tasks/tasks.rake +0 -48
  125. data/spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb +0 -46
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # This controller is meant to be something that inherits config from application controller
4
- # all values are defaulted because no initializer is configured, and the values in app controller
5
- # only provide csp => false
6
-
7
- describe ThingsController, :type => :controller do
8
- describe "headers" do
9
- it "sets the X-XSS-Protection header" do
10
- get :index
11
- expect(response.headers['X-XSS-Protection']).to eq(SecureHeaders::XXssProtection::Constants::DEFAULT_VALUE)
12
- end
13
-
14
- it "sets the X-Frame-Options header" do
15
- get :index
16
- expect(response.headers['X-Frame-Options']).to eq(SecureHeaders::XFrameOptions::Constants::DEFAULT_VALUE)
17
- end
18
-
19
- it "sets the X-WebKit-CSP header" do
20
- get :index
21
- expect(response.headers['Content-Security-Policy-Report-Only']).to eq(nil)
22
- end
23
-
24
- #mock ssl
25
- it "sets the Strict-Transport-Security header" do
26
- request.env['HTTPS'] = 'on'
27
- get :index
28
- expect(response.headers['Strict-Transport-Security']).to eq(SecureHeaders::StrictTransportSecurity::Constants::DEFAULT_VALUE)
29
- end
30
-
31
- it "sets the X-Download-Options header" do
32
- get :index
33
- expect(response.headers['X-Download-Options']).to eq(SecureHeaders::XDownloadOptions::Constants::DEFAULT_VALUE)
34
- end
35
-
36
- it "sets the X-Content-Type-Options header" do
37
- get :index
38
- expect(response.headers['X-Content-Type-Options']).to eq(SecureHeaders::XContentTypeOptions::Constants::DEFAULT_VALUE)
39
- end
40
-
41
- it "sets the X-Permitted-Cross-Domain-Policies" do
42
- get :index
43
- expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
44
- end
45
-
46
- context "using IE" do
47
- it "sets the X-Content-Type-Options header" do
48
- request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
49
- get :index
50
- expect(response.headers['X-Content-Type-Options']).to eq(SecureHeaders::XContentTypeOptions::Constants::DEFAULT_VALUE)
51
- end
52
- end
53
- end
54
- end
@@ -1,5 +0,0 @@
1
- require 'rubygems'
2
-
3
- ENV["RAILS_ENV"] ||= 'test'
4
- require File.expand_path("../../config/environment", __FILE__)
5
- require 'rspec/rails'
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '4.1.8'
4
- gem 'rspec-rails', '>= 2.0.0'
5
- gem 'secure_headers', :path => '../..'
@@ -1,28 +0,0 @@
1
- == README
2
-
3
- This README would normally document whatever steps are necessary to get the
4
- application up and running.
5
-
6
- Things you may want to cover:
7
-
8
- * Ruby version
9
-
10
- * System dependencies
11
-
12
- * Configuration
13
-
14
- * Database creation
15
-
16
- * Database initialization
17
-
18
- * How to run the test suite
19
-
20
- * Services (job queues, cache servers, search engines, etc.)
21
-
22
- * Deployment instructions
23
-
24
- * ...
25
-
26
-
27
- Please feel free to use a different markup language if you do not plan to run
28
- <tt>rake doc:app</tt>.
@@ -1,6 +0,0 @@
1
- # Add your own tasks in files placed in lib/tasks ending in .rake,
2
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
-
4
- require File.expand_path('../config/application', __FILE__)
5
-
6
- Rails.application.load_tasks
@@ -1,4 +0,0 @@
1
- class ApplicationController < ActionController::Base
2
- protect_from_forgery
3
- ensure_security_headers
4
- end
File without changes
@@ -1,5 +0,0 @@
1
- class OtherThingsController < ApplicationController
2
- def index
3
-
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- class ThingsController < ApplicationController
2
- ensure_security_headers :csp => false
3
- def index
4
- end
5
- end
File without changes
File without changes
@@ -1,11 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Rails418</title>
5
- </head>
6
- <body>
7
-
8
- <%= yield %>
9
- <script>console.log("oh hell yes")</script>
10
- </body>
11
- </html>
@@ -1,2 +0,0 @@
1
- index
2
- <script>console.log("oh what")</script>
@@ -1,15 +0,0 @@
1
- require File.expand_path('../boot', __FILE__)
2
-
3
- require "action_controller/railtie"
4
- require "sprockets/railtie"
5
-
6
- # Require the gems listed in Gemfile, including any gems
7
- # you've limited to :test, :development, or :production.
8
- Bundler.require(*Rails.groups)
9
-
10
-
11
- module Rails418
12
- class Application < Rails::Application
13
-
14
- end
15
- end
@@ -1,4 +0,0 @@
1
- # Set up gems listed in the Gemfile.
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
-
4
- require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -1,5 +0,0 @@
1
- # Load the Rails application.
2
- require File.expand_path('../application', __FILE__)
3
-
4
- # Initialize the Rails application.
5
- Rails.application.initialize!
@@ -1,10 +0,0 @@
1
- Rails418::Application.configure do
2
- config.cache_classes = true
3
- config.eager_load = false
4
- config.serve_static_assets = true
5
- config.static_cache_control = 'public, max-age=3600'
6
- config.consider_all_requests_local = true
7
- config.action_controller.perform_caching = false
8
- config.action_dispatch.show_exceptions = false
9
- config.action_controller.allow_forgery_protection = false
10
- end
@@ -1,16 +0,0 @@
1
- ::SecureHeaders::Configuration.configure do |config|
2
- config.hsts = { :max_age => 10.years.to_i.to_s, :include_subdomains => false }
3
- config.x_frame_options = 'DENY'
4
- config.x_content_type_options = "nosniff"
5
- config.x_xss_protection = {:value => 0}
6
- config.x_permitted_cross_domain_policies = 'none'
7
- csp = {
8
- :default_src => "'self'",
9
- :script_src => "'self' nonce",
10
- :report_uri => 'somewhere',
11
- :script_hash_middleware => true,
12
- :enforce => false # false means warnings only
13
- }
14
-
15
- config.csp = csp
16
- end
@@ -1,4 +0,0 @@
1
- Rails.application.routes.draw do
2
- resources :things
3
- match ':controller(/:action(/:id))(.:format)', :via => [:get, :post]
4
- end
@@ -1,5 +0,0 @@
1
- ---
2
- app/views/layouts/application.html.erb:
3
- - sha256-VjDxT7saxd2FgaUQQTWw/jsTnvonaoCP/ACWDBTpyhU=
4
- app/views/other_things/index.html.erb:
5
- - sha256-ZXAcP8a0y1pPMTJW8pUr43c+XBkgYQBwHOPvXk9mq5A=
@@ -1,22 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # Your secret key is used for verifying the integrity of signed cookies.
4
- # If you change this key, all old signed cookies will become invalid!
5
-
6
- # Make sure the secret is at least 30 characters and all random,
7
- # no regular words or you'll be exposed to dictionary attacks.
8
- # You can use `rake secret` to generate a secure secret key.
9
-
10
- # Make sure the secrets in this file are kept private
11
- # if you're sharing your code publicly.
12
-
13
- development:
14
- secret_key_base: ddba38f932720d8f18257f2a05dc278963a29cf569c45aa97ff4e9fc9bbc78af5a03fcf135caad45caee66ac09f8f9913c1f5e338a61213f420eefa8dd6363d2
15
-
16
- test:
17
- secret_key_base: f73abd7eab84fa7af5a2fc0a9c2727c5bad47433e51aa0c9c6b0782dac176a8e7f337e1f93adc6d6fc17027e67a533040b6408e54d72dea2eec6e5b9820dbcb9
18
-
19
- # Do not keep production secrets in the repository,
20
- # instead read values from the environment.
21
- production:
22
- secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -1,4 +0,0 @@
1
- # This file is used by Rack-based servers to start the application.
2
-
3
- require ::File.expand_path('../config/environment', __FILE__)
4
- run Rails.application
File without changes
File without changes
File without changes
@@ -1,83 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'secure_headers/headers/content_security_policy/script_hash_middleware'
4
-
5
- describe OtherThingsController, :type => :controller do
6
- include Rack::Test::Methods
7
-
8
- def app
9
- OtherThingsController.action(:index)
10
- end
11
-
12
- def request(opts = {})
13
- options = opts.merge(
14
- {
15
- 'HTTPS' => 'on',
16
- 'HTTP_USER_AGENT' => "Mozilla/5.0 (Macintosh; Intel Mac OS X 1084) AppleWebKit/537.22 (KHTML like Gecko) Chrome/25.0.1364.99 Safari/537.22"
17
- }
18
- )
19
-
20
-
21
- Rack::MockRequest.env_for('/', options)
22
- end
23
-
24
-
25
- describe "headers" do
26
- before(:each) do
27
- _, @env = app.call(request)
28
- end
29
-
30
- it "sets the X-XSS-Protection header" do
31
- get '/'
32
- expect(@env['X-XSS-Protection']).to eq('0')
33
- end
34
-
35
- it "sets the X-Frame-Options header" do
36
- get '/'
37
- expect(@env['X-Frame-Options']).to eq('DENY')
38
- end
39
-
40
- it "sets the CSP header with a local reference to a nonce" do
41
- middleware = ::SecureHeaders::ContentSecurityPolicy::ScriptHashMiddleware.new(app)
42
- _, env = middleware.call(request(@env))
43
- expect(env['Content-Security-Policy-Report-Only']).to match(/script-src[^;]*'nonce-[a-zA-Z0-9\+\/=]{44}'/)
44
- end
45
-
46
- it "sets the required hashes to whitelist inline script" do
47
- middleware = ::SecureHeaders::ContentSecurityPolicy::ScriptHashMiddleware.new(app)
48
- _, env = middleware.call(request(@env))
49
- hashes = ['sha256-VjDxT7saxd2FgaUQQTWw/jsTnvonaoCP/ACWDBTpyhU=', 'sha256-ZXAcP8a0y1pPMTJW8pUr43c+XBkgYQBwHOPvXk9mq5A=']
50
- hashes.each do |hash|
51
- expect(env['Content-Security-Policy-Report-Only']).to include(hash)
52
- end
53
- end
54
-
55
- it "sets the Strict-Transport-Security header" do
56
- get '/'
57
- expect(@env['Strict-Transport-Security']).to eq("max-age=315576000")
58
- end
59
-
60
- it "sets the X-Download-Options header" do
61
- get '/'
62
- expect(@env['X-Download-Options']).to eq('noopen')
63
- end
64
-
65
- it "sets the X-Content-Type-Options header" do
66
- get '/'
67
- expect(@env['X-Content-Type-Options']).to eq("nosniff")
68
- end
69
-
70
- it "sets the X-Permitted-Cross-Domain-Policies" do
71
- get '/'
72
- expect(@env['X-Permitted-Cross-Domain-Policies']).to eq("none")
73
- end
74
-
75
- context "using IE" do
76
- it "sets the X-Content-Type-Options header" do
77
- @env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
78
- get '/'
79
- expect(@env['X-Content-Type-Options']).to eq("nosniff")
80
- end
81
- end
82
- end
83
- end
@@ -1,59 +0,0 @@
1
- # config.action_dispatch.default_headers defaults to:
2
- # {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}
3
- # so we want to set our specs to expect something else to ensure secureheaders is taking precedence
4
-
5
- require 'spec_helper'
6
-
7
- # This controller is meant to be something that inherits config from application controller
8
- # all values are defaulted because no initializer is configured, and the values in app controller
9
- # only provide csp => false
10
-
11
- describe ThingsController, :type => :controller do
12
-
13
- describe "headers" do
14
- it "sets the X-XSS-Protection header" do
15
- get :index
16
- expect(response.headers['X-XSS-Protection']).to eq('0')
17
- end
18
-
19
- it "sets the X-Frame-Options header" do
20
- get :index
21
- expect(response.headers['X-Frame-Options']).to eq('DENY')
22
- end
23
-
24
- it "does not set CSP header" do
25
- get :index
26
- expect(response.headers['Content-Security-Policy-Report-Only']).to eq(nil)
27
- end
28
-
29
- #mock ssl
30
- it "sets the Strict-Transport-Security header" do
31
- request.env['HTTPS'] = 'on'
32
- get :index
33
- expect(response.headers['Strict-Transport-Security']).to eq("max-age=315576000")
34
- end
35
-
36
- it "sets the X-Download-Options header" do
37
- get :index
38
- expect(response.headers['X-Download-Options']).to eq('noopen')
39
- end
40
-
41
- it "sets the X-Content-Type-Options header" do
42
- get :index
43
- expect(response.headers['X-Content-Type-Options']).to eq("nosniff")
44
- end
45
-
46
- it "sets the X-Permitted-Cross-Domain-Policies" do
47
- get :index
48
- expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
49
- end
50
-
51
- context "using IE" do
52
- it "sets the X-Content-Type-Options header" do
53
- request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; MSIE 10.6; Windows NT 6.1; Trident/5.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727) 3gpp-gba UNTRUSTED/1.0"
54
- get :index
55
- expect(response.headers['X-Content-Type-Options']).to eq("nosniff")
56
- end
57
- end
58
- end
59
- end
@@ -1,15 +0,0 @@
1
- require 'rubygems'
2
-
3
- #uncomment the following line to use spork with the debugger
4
- #require 'spork/ext/ruby-debug'
5
-
6
- # Spork.prefork do
7
- # Loading more in this block will cause your tests to run faster. However,
8
- # if you change any configuration or code from libraries loaded here, you'll
9
- # need to restart spork for it take effect.
10
- # This file is copied to spec/ when you run 'rails generate rspec:install'
11
- ENV["RAILS_ENV"] ||= 'test'
12
- require File.expand_path("../../config/environment", __FILE__)
13
- require 'rspec/rails'
14
- # end
15
-
File without changes
File without changes
@@ -1,158 +0,0 @@
1
- module SecureHeaders
2
- module ControllerExtension
3
- class << self
4
- def append_features(base)
5
- base.module_eval do
6
- extend ClassMethods
7
- include InstanceMethods
8
- end
9
- end
10
- end
11
-
12
- module ClassMethods
13
- attr_writer :secure_headers_options
14
- def secure_headers_options
15
- if @secure_headers_options
16
- @secure_headers_options
17
- elsif superclass.respond_to?(:secure_headers_options) # stop at application_controller
18
- superclass.secure_headers_options
19
- else
20
- {}
21
- end
22
- end
23
-
24
- def ensure_security_headers options = {}
25
- if RUBY_VERSION == "1.8.7"
26
- warn "[DEPRECATION] secure_headers ruby 1.8.7 support will dropped in the next release"
27
- end
28
- self.secure_headers_options = options
29
- hook = respond_to?(:before_action) ? :before_action : :before_filter
30
- ::SecureHeaders::ALL_FILTER_METHODS.each do |method|
31
- send(hook, method)
32
- end
33
- end
34
- end
35
-
36
- module InstanceMethods
37
- def set_security_headers(options = self.class.secure_headers_options)
38
- set_csp_header(request, options[:csp])
39
- set_hsts_header(options[:hsts])
40
- set_hpkp_header(options[:hpkp])
41
- set_x_frame_options_header(options[:x_frame_options])
42
- set_x_xss_protection_header(options[:x_xss_protection])
43
- set_x_content_type_options_header(options[:x_content_type_options])
44
- set_x_download_options_header(options[:x_download_options])
45
- set_x_permitted_cross_domain_policies_header(options[:x_permitted_cross_domain_policies])
46
- end
47
-
48
- # set_csp_header - uses the request accessor and SecureHeader::Configuration settings
49
- # set_csp_header(+Rack::Request+) - uses the parameter and and SecureHeader::Configuration settings
50
- # set_csp_header(+Hash+) - uses the request accessor and options from parameters
51
- # set_csp_header(+Rack::Request+, +Hash+)
52
- def set_csp_header(req = nil, config=nil)
53
- if req.is_a?(Hash) || req.is_a?(FalseClass)
54
- config = req
55
- end
56
-
57
- config = self.class.secure_headers_options[:csp] if config.nil?
58
- config = secure_header_options_for :csp, config
59
-
60
- return if config == false
61
-
62
- if config && config[:script_hash_middleware]
63
- ContentSecurityPolicy.add_to_env(request, self, config)
64
- else
65
- csp_header = ContentSecurityPolicy.new(config, :request => request, :controller => self)
66
- set_header(csp_header)
67
- end
68
- end
69
-
70
-
71
- def prep_script_hash
72
- if ::SecureHeaders::Configuration.script_hashes
73
- @script_hashes = ::SecureHeaders::Configuration.script_hashes.dup
74
- ActiveSupport::Notifications.subscribe("render_partial.action_view") do |event_name, start_at, end_at, id, payload|
75
- save_hash_for_later payload
76
- end
77
-
78
- ActiveSupport::Notifications.subscribe("render_template.action_view") do |event_name, start_at, end_at, id, payload|
79
- save_hash_for_later payload
80
- end
81
- end
82
- end
83
-
84
- def save_hash_for_later payload
85
- matching_hashes = @script_hashes[payload[:identifier].gsub(Rails.root.to_s + "/", "")] || []
86
-
87
- if payload[:layout]
88
- # We're assuming an html.erb layout for now. Will need to handle mustache too, just not sure of the best way to do this
89
- layout_hashes = @script_hashes[File.join("app", "views", payload[:layout]) + '.html.erb']
90
-
91
- matching_hashes << layout_hashes if layout_hashes
92
- end
93
-
94
- if matching_hashes.any?
95
- request.env[HASHES_ENV_KEY] = ((request.env[HASHES_ENV_KEY] || []) << matching_hashes).flatten
96
- end
97
- end
98
-
99
- def set_x_frame_options_header(options=self.class.secure_headers_options[:x_frame_options])
100
- set_a_header(:x_frame_options, XFrameOptions, options)
101
- end
102
-
103
- def set_x_content_type_options_header(options=self.class.secure_headers_options[:x_content_type_options])
104
- set_a_header(:x_content_type_options, XContentTypeOptions, options)
105
- end
106
-
107
- def set_x_xss_protection_header(options=self.class.secure_headers_options[:x_xss_protection])
108
- set_a_header(:x_xss_protection, XXssProtection, options)
109
- end
110
-
111
- def set_hsts_header(options=self.class.secure_headers_options[:hsts])
112
- return unless request.ssl?
113
- set_a_header(:hsts, StrictTransportSecurity, options)
114
- end
115
-
116
- def set_hpkp_header(options=self.class.secure_headers_options[:hpkp])
117
- return unless request.ssl?
118
- config = secure_header_options_for :hpkp, options
119
-
120
- return if config == false || config.nil?
121
-
122
- hpkp_header = PublicKeyPins.new(config)
123
- set_header(hpkp_header)
124
- end
125
-
126
- def set_x_download_options_header(options=self.class.secure_headers_options[:x_download_options])
127
- set_a_header(:x_download_options, XDownloadOptions, options)
128
- end
129
-
130
- def set_x_permitted_cross_domain_policies_header(options=self.class.secure_headers_options[:x_permitted_cross_domain_policies])
131
- set_a_header(:x_permitted_cross_domain_policies, XPermittedCrossDomainPolicies, options)
132
- end
133
-
134
- private
135
-
136
- # we can't use ||= because I'm overloading false => disable, nil => default
137
- # both of which trigger the conditional assignment
138
- def secure_header_options_for(type, options)
139
- options.nil? ? ::SecureHeaders::Configuration.send(type) : options
140
- end
141
-
142
- def set_a_header(name, klass, options=nil)
143
- options = secure_header_options_for(name, options)
144
- return if options == false
145
- set_header(SecureHeaders::get_a_header(klass, options))
146
- end
147
-
148
- def set_header(name_or_header, value=nil)
149
- if name_or_header.is_a?(Header)
150
- header = name_or_header
151
- response.headers[header.name] = header.value
152
- else
153
- response.headers[name_or_header] = value
154
- end
155
- end
156
- end
157
- end
158
- end
@@ -1,7 +0,0 @@
1
- module SecureHeaders
2
- module HashHelper
3
- def hash_source(inline_script, digest = :SHA256)
4
- [digest.to_s.downcase, "-", [[Digest.const_get(digest).hexdigest(inline_script)].pack("H*")].pack("m").chomp].join
5
- end
6
- end
7
- end
@@ -1,5 +0,0 @@
1
- module SecureHeaders
2
- class Header
3
-
4
- end
5
- end
@@ -1,22 +0,0 @@
1
- module SecureHeaders
2
- class ContentSecurityPolicy
3
- class ScriptHashMiddleware
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def call(env)
9
- status, headers, response = @app.call(env)
10
- metadata = env[ContentSecurityPolicy::ENV_KEY]
11
- if !metadata.nil?
12
- config, options = metadata.values_at(:config, :options)
13
- config.merge!(:script_hashes => env[HASHES_ENV_KEY])
14
- csp_header = ContentSecurityPolicy.new(config, options)
15
- headers[csp_header.name] = csp_header.value
16
- end
17
-
18
- [status, headers, response]
19
- end
20
- end
21
- end
22
- end
@@ -1,3 +0,0 @@
1
- module SecureHeaders
2
- VERSION = "2.5.3"
3
- end