Rails 4 specs
This commit is contained in:
Родитель
b8bb092dc6
Коммит
69f9a3d4b7
11
Rakefile
11
Rakefile
|
@ -33,6 +33,17 @@ task :all_spec => :spec do
|
|||
fail "Header tests with app not using initializer failed"
|
||||
Dir.chdir pwd
|
||||
end
|
||||
|
||||
Dir.chdir pwd
|
||||
Dir.chdir 'fixtures/rails_4_1_8'
|
||||
puts Dir.pwd
|
||||
puts `bundle install >> /dev/null; bundle exec rspec spec`
|
||||
|
||||
unless $? == 0
|
||||
fail "Header tests with Rails 4 failed"
|
||||
Dir.chdir pwd
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
begin
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '4.1.8'
|
||||
gem 'rspec-rails', '>= 2.0.0'
|
||||
gem 'secure_headers', :path => '../..'
|
|
@ -0,0 +1,28 @@
|
|||
== README
|
||||
|
||||
This README would normally document whatever steps are necessary to get the
|
||||
application up and running.
|
||||
|
||||
Things you may want to cover:
|
||||
|
||||
* Ruby version
|
||||
|
||||
* System dependencies
|
||||
|
||||
* Configuration
|
||||
|
||||
* Database creation
|
||||
|
||||
* Database initialization
|
||||
|
||||
* How to run the test suite
|
||||
|
||||
* Services (job queues, cache servers, search engines, etc.)
|
||||
|
||||
* Deployment instructions
|
||||
|
||||
* ...
|
||||
|
||||
|
||||
Please feel free to use a different markup language if you do not plan to run
|
||||
<tt>rake doc:app</tt>.
|
|
@ -0,0 +1,6 @@
|
|||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
|
||||
Rails.application.load_tasks
|
|
@ -0,0 +1,4 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
ensure_security_headers
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class OtherThingsController < ApplicationController
|
||||
def index
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class ThingsController < ApplicationController
|
||||
ensure_security_headers :csp => false
|
||||
def index
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Rails418</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<%= yield %>
|
||||
<script>console.log("oh hell yes")</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
index
|
||||
<script>console.log("oh what")</script>
|
|
@ -0,0 +1 @@
|
|||
things
|
|
@ -0,0 +1,4 @@
|
|||
# This file is used by Rack-based servers to start the application.
|
||||
|
||||
require ::File.expand_path('../config/environment', __FILE__)
|
||||
run Rails.application
|
|
@ -0,0 +1,15 @@
|
|||
require File.expand_path('../boot', __FILE__)
|
||||
|
||||
require "action_controller/railtie"
|
||||
require "sprockets/railtie"
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups)
|
||||
|
||||
|
||||
module Rails418
|
||||
class Application < Rails::Application
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
# Set up gems listed in the Gemfile.
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
|
||||
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
|
@ -0,0 +1,5 @@
|
|||
# Load the Rails application.
|
||||
require File.expand_path('../application', __FILE__)
|
||||
|
||||
# Initialize the Rails application.
|
||||
Rails.application.initialize!
|
|
@ -0,0 +1,10 @@
|
|||
Rails418::Application.configure do
|
||||
config.cache_classes = true
|
||||
config.eager_load = false
|
||||
config.serve_static_assets = true
|
||||
config.static_cache_control = 'public, max-age=3600'
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
config.action_dispatch.show_exceptions = false
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
::SecureHeaders::Configuration.configure do |config|
|
||||
config.hsts = { :max_age => 10.years.to_i.to_s, :include_subdomains => false }
|
||||
config.x_frame_options = 'DENY'
|
||||
config.x_content_type_options = "nosniff"
|
||||
config.x_xss_protection = {:value => 0}
|
||||
config.x_permitted_cross_domain_policies = 'none'
|
||||
csp = {
|
||||
:default_src => "self",
|
||||
:script_src => "self nonce",
|
||||
:disable_fill_missing => true,
|
||||
:report_uri => 'somewhere',
|
||||
:script_hash_middleware => true,
|
||||
:enforce => false # false means warnings only
|
||||
}
|
||||
|
||||
config.csp = csp
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
Rails.application.routes.draw do
|
||||
resources :things
|
||||
match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
app/views/layouts/application.html.erb:
|
||||
- sha256-VjDxT7saxd2FgaUQQTWw/jsTnvonaoCP/ACWDBTpyhU=
|
||||
app/views/other_things/index.html.erb:
|
||||
- sha256-ZXAcP8a0y1pPMTJW8pUr43c+XBkgYQBwHOPvXk9mq5A=
|
|
@ -0,0 +1,22 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
# You can use `rake secret` to generate a secure secret key.
|
||||
|
||||
# Make sure the secrets in this file are kept private
|
||||
# if you're sharing your code publicly.
|
||||
|
||||
development:
|
||||
secret_key_base: ddba38f932720d8f18257f2a05dc278963a29cf569c45aa97ff4e9fc9bbc78af5a03fcf135caad45caee66ac09f8f9913c1f5e338a61213f420eefa8dd6363d2
|
||||
|
||||
test:
|
||||
secret_key_base: f73abd7eab84fa7af5a2fc0a9c2727c5bad47433e51aa0c9c6b0782dac176a8e7f337e1f93adc6d6fc17027e67a533040b6408e54d72dea2eec6e5b9820dbcb9
|
||||
|
||||
# Do not keep production secrets in the repository,
|
||||
# instead read values from the environment.
|
||||
production:
|
||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
|
@ -0,0 +1,83 @@
|
|||
require 'spec_helper'
|
||||
|
||||
require 'secure_headers/headers/content_security_policy/script_hash_middleware'
|
||||
|
||||
describe OtherThingsController, :type => :controller do
|
||||
include Rack::Test::Methods
|
||||
|
||||
def app
|
||||
OtherThingsController.action(:index)
|
||||
end
|
||||
|
||||
def request(opts = {})
|
||||
options = opts.merge(
|
||||
{
|
||||
'HTTPS' => 'on',
|
||||
'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"
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Rack::MockRequest.env_for('/', options)
|
||||
end
|
||||
|
||||
|
||||
describe "headers" do
|
||||
before(:each) do
|
||||
_, @env = app.call(request)
|
||||
end
|
||||
|
||||
it "sets the X-XSS-Protection header" do
|
||||
get '/'
|
||||
expect(@env['X-XSS-Protection']).to eq('0')
|
||||
end
|
||||
|
||||
it "sets the X-Frame-Options header" do
|
||||
get '/'
|
||||
expect(@env['X-Frame-Options']).to eq('DENY')
|
||||
end
|
||||
|
||||
it "sets the CSP header with a local reference to a nonce" do
|
||||
middleware = ::SecureHeaders::ContentSecurityPolicy::ScriptHashMiddleware.new(app)
|
||||
_, env = middleware.call(request(@env))
|
||||
expect(env['Content-Security-Policy-Report-Only']).to match(/script-src[^;]*'nonce-[a-zA-Z0-9\+\/=]{44}'/)
|
||||
end
|
||||
|
||||
it "sets the required hashes to whitelist inline script" do
|
||||
middleware = ::SecureHeaders::ContentSecurityPolicy::ScriptHashMiddleware.new(app)
|
||||
_, env = middleware.call(request(@env))
|
||||
hashes = ['sha256-VjDxT7saxd2FgaUQQTWw/jsTnvonaoCP/ACWDBTpyhU=', 'sha256-ZXAcP8a0y1pPMTJW8pUr43c+XBkgYQBwHOPvXk9mq5A=']
|
||||
hashes.each do |hash|
|
||||
expect(env['Content-Security-Policy-Report-Only']).to include(hash)
|
||||
end
|
||||
end
|
||||
|
||||
it "sets the Strict-Transport-Security header" do
|
||||
get '/'
|
||||
expect(@env['Strict-Transport-Security']).to eq("max-age=315576000")
|
||||
end
|
||||
|
||||
it "sets the X-Download-Options header" do
|
||||
get '/'
|
||||
expect(@env['X-Download-Options']).to eq('noopen')
|
||||
end
|
||||
|
||||
it "sets the X-Content-Type-Options header" do
|
||||
get '/'
|
||||
expect(@env['X-Content-Type-Options']).to eq("nosniff")
|
||||
end
|
||||
|
||||
it "sets the X-Permitted-Cross-Domain-Policies" do
|
||||
get '/'
|
||||
expect(@env['X-Permitted-Cross-Domain-Policies']).to eq("none")
|
||||
end
|
||||
|
||||
context "using IE" do
|
||||
it "sets the X-Content-Type-Options header" do
|
||||
@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"
|
||||
get '/'
|
||||
expect(@env['X-Content-Type-Options']).to eq("nosniff")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
# config.action_dispatch.default_headers defaults to:
|
||||
# {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}
|
||||
# so we want to set our specs to expect something else to ensure secureheaders is taking precedence
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
# This controller is meant to be something that inherits config from application controller
|
||||
# all values are defaulted because no initializer is configured, and the values in app controller
|
||||
# only provide csp => false
|
||||
|
||||
describe ThingsController, :type => :controller do
|
||||
|
||||
describe "headers" do
|
||||
it "sets the X-XSS-Protection header" do
|
||||
get :index
|
||||
expect(response.headers['X-XSS-Protection']).to eq('0')
|
||||
end
|
||||
|
||||
it "sets the X-Frame-Options header" do
|
||||
get :index
|
||||
expect(response.headers['X-Frame-Options']).to eq('DENY')
|
||||
end
|
||||
|
||||
it "does not set CSP header" do
|
||||
get :index
|
||||
expect(response.headers['Content-Security-Policy-Report-Only']).to eq(nil)
|
||||
end
|
||||
|
||||
#mock ssl
|
||||
it "sets the Strict-Transport-Security header" do
|
||||
request.env['HTTPS'] = 'on'
|
||||
get :index
|
||||
expect(response.headers['Strict-Transport-Security']).to eq("max-age=315576000")
|
||||
end
|
||||
|
||||
it "sets the X-Download-Options header" do
|
||||
get :index
|
||||
expect(response.headers['X-Download-Options']).to eq('noopen')
|
||||
end
|
||||
|
||||
it "sets the X-Content-Type-Options header" do
|
||||
get :index
|
||||
expect(response.headers['X-Content-Type-Options']).to eq("nosniff")
|
||||
end
|
||||
|
||||
it "sets the X-Permitted-Cross-Domain-Policies" do
|
||||
get :index
|
||||
expect(response.headers['X-Permitted-Cross-Domain-Policies']).to eq("none")
|
||||
end
|
||||
|
||||
context "using IE" do
|
||||
it "sets the X-Content-Type-Options header" do
|
||||
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"
|
||||
get :index
|
||||
expect(response.headers['X-Content-Type-Options']).to eq("nosniff")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
require 'rubygems'
|
||||
|
||||
#uncomment the following line to use spork with the debugger
|
||||
#require 'spork/ext/ruby-debug'
|
||||
|
||||
# Spork.prefork do
|
||||
# Loading more in this block will cause your tests to run faster. However,
|
||||
# if you change any configuration or code from libraries loaded here, you'll
|
||||
# need to restart spork for it take effect.
|
||||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
require File.expand_path("../../config/environment", __FILE__)
|
||||
require 'rspec/rails'
|
||||
# end
|
||||
|
Загрузка…
Ссылка в новой задаче