secure_headers 1.0.0 → 2.0.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.
- data/.gitignore +4 -8
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -3
- data/Gemfile +6 -8
- data/README.md +208 -134
- data/Rakefile +11 -116
- data/fixtures/rails_3_2_12/Gemfile +0 -8
- data/fixtures/rails_3_2_12/app/controllers/things_controller.rb +0 -1
- data/fixtures/rails_3_2_12/app/views/layouts/application.html.erb +1 -4
- data/fixtures/rails_3_2_12/app/views/other_things/index.html.erb +2 -1
- data/fixtures/rails_3_2_12/app/views/things/index.html.erb +1 -21
- data/fixtures/rails_3_2_12/config/application.rb +0 -54
- data/fixtures/rails_3_2_12/config/environments/test.rb +2 -2
- data/fixtures/rails_3_2_12/config/initializers/secure_headers.rb +3 -1
- data/fixtures/rails_3_2_12/config/routes.rb +0 -57
- data/fixtures/rails_3_2_12/config/script_hashes.yml +5 -0
- data/fixtures/rails_3_2_12/config.ru +3 -0
- data/fixtures/rails_3_2_12/spec/controllers/other_things_controller_spec.rb +57 -19
- data/fixtures/rails_3_2_12/spec/controllers/things_controller_spec.rb +18 -16
- data/fixtures/rails_3_2_12/spec/spec_helper.rb +1 -5
- data/fixtures/rails_3_2_12_no_init/Gemfile +0 -9
- data/fixtures/rails_3_2_12_no_init/app/controllers/other_things_controller.rb +1 -2
- data/fixtures/rails_3_2_12_no_init/app/controllers/things_controller.rb +1 -1
- data/fixtures/rails_3_2_12_no_init/app/views/layouts/application.html.erb +0 -2
- data/fixtures/rails_3_2_12_no_init/app/views/things/index.html.erb +0 -21
- data/fixtures/rails_3_2_12_no_init/config/application.rb +0 -51
- data/fixtures/rails_3_2_12_no_init/config/environments/test.rb +2 -2
- data/fixtures/rails_3_2_12_no_init/config/routes.rb +0 -57
- data/fixtures/rails_3_2_12_no_init/spec/controllers/other_things_controller_spec.rb +17 -12
- data/fixtures/rails_3_2_12_no_init/spec/controllers/things_controller_spec.rb +17 -12
- data/fixtures/rails_3_2_12_no_init/spec/spec_helper.rb +3 -18
- data/fixtures/rails_4_1_8/Gemfile +5 -0
- data/fixtures/rails_4_1_8/README.rdoc +28 -0
- data/fixtures/rails_4_1_8/Rakefile +6 -0
- data/fixtures/rails_4_1_8/app/controllers/application_controller.rb +4 -0
- data/fixtures/rails_4_1_8/app/controllers/concerns/.keep +0 -0
- data/fixtures/rails_4_1_8/app/controllers/other_things_controller.rb +5 -0
- data/fixtures/rails_4_1_8/app/controllers/things_controller.rb +5 -0
- data/fixtures/rails_4_1_8/app/models/.keep +0 -0
- data/fixtures/rails_4_1_8/app/models/concerns/.keep +0 -0
- data/fixtures/rails_4_1_8/app/views/layouts/application.html.erb +11 -0
- data/fixtures/rails_4_1_8/app/views/other_things/index.html.erb +2 -0
- data/fixtures/rails_4_1_8/app/views/things/index.html.erb +1 -0
- data/fixtures/rails_4_1_8/config/application.rb +15 -0
- data/fixtures/rails_4_1_8/config/boot.rb +4 -0
- data/fixtures/rails_4_1_8/config/environment.rb +5 -0
- data/fixtures/rails_4_1_8/config/environments/test.rb +10 -0
- data/fixtures/rails_4_1_8/config/initializers/secure_headers.rb +17 -0
- data/fixtures/rails_4_1_8/config/routes.rb +4 -0
- data/fixtures/rails_4_1_8/config/script_hashes.yml +5 -0
- data/fixtures/rails_4_1_8/config/secrets.yml +22 -0
- data/fixtures/rails_4_1_8/config.ru +4 -0
- data/fixtures/rails_4_1_8/lib/assets/.keep +0 -0
- data/fixtures/rails_4_1_8/lib/tasks/.keep +0 -0
- data/fixtures/rails_4_1_8/log/.keep +0 -0
- data/fixtures/rails_4_1_8/spec/controllers/other_things_controller_spec.rb +83 -0
- data/fixtures/rails_4_1_8/spec/controllers/things_controller_spec.rb +59 -0
- data/fixtures/rails_4_1_8/spec/spec_helper.rb +15 -0
- data/fixtures/rails_4_1_8/vendor/assets/javascripts/.keep +0 -0
- data/fixtures/rails_4_1_8/vendor/assets/stylesheets/.keep +0 -0
- data/lib/secure_headers/hash_helper.rb +7 -0
- data/lib/secure_headers/headers/content_security_policy/script_hash_middleware.rb +22 -0
- data/lib/secure_headers/headers/content_security_policy.rb +160 -161
- data/lib/secure_headers/headers/strict_transport_security.rb +2 -1
- data/lib/secure_headers/headers/x_download_options.rb +39 -0
- data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +40 -0
- data/lib/secure_headers/headers/x_xss_protection.rb +2 -1
- data/lib/secure_headers/padrino.rb +14 -0
- data/lib/secure_headers/railtie.rb +19 -24
- data/lib/secure_headers/version.rb +1 -1
- data/lib/secure_headers/view_helper.rb +68 -0
- data/lib/secure_headers.rb +70 -29
- data/lib/tasks/tasks.rake +48 -0
- data/secure_headers.gemspec +4 -5
- data/spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb +47 -0
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +127 -299
- data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +21 -20
- data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +12 -12
- data/spec/lib/secure_headers/headers/x_download_options_spec.rb +32 -0
- data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +12 -13
- data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +64 -0
- data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +20 -19
- data/spec/lib/secure_headers_spec.rb +68 -83
- data/spec/spec_helper.rb +29 -18
- metadata +51 -66
- data/.rvmrc +0 -1
- data/Guardfile +0 -10
- data/HISTORY.md +0 -100
- data/app/controllers/content_security_policy_controller.rb +0 -53
- data/config/curl-ca-bundle.crt +0 -5420
- data/config/routes.rb +0 -3
- data/fixtures/rails_3_2_12/Guardfile +0 -14
- data/fixtures/rails_3_2_12/app/models/thing.rb +0 -3
- data/fixtures/rails_3_2_12/config/database.yml +0 -25
- data/fixtures/rails_3_2_12/config/environments/development.rb +0 -37
- data/fixtures/rails_3_2_12/config/environments/production.rb +0 -67
- data/fixtures/rails_3_2_12/config/initializers/backtrace_silencers.rb +0 -7
- data/fixtures/rails_3_2_12/config/initializers/inflections.rb +0 -15
- data/fixtures/rails_3_2_12/config/initializers/mime_types.rb +0 -5
- data/fixtures/rails_3_2_12/config/initializers/secret_token.rb +0 -7
- data/fixtures/rails_3_2_12/config/initializers/session_store.rb +0 -8
- data/fixtures/rails_3_2_12/config/initializers/wrap_parameters.rb +0 -14
- data/fixtures/rails_3_2_12/config/locales/en.yml +0 -5
- data/fixtures/rails_3_2_12/db/schema.rb +0 -16
- data/fixtures/rails_3_2_12/db/seeds.rb +0 -7
- data/fixtures/rails_3_2_12_no_init/Guardfile +0 -14
- data/fixtures/rails_3_2_12_no_init/app/models/thing.rb +0 -3
- data/fixtures/rails_3_2_12_no_init/app/views/things/_form.html.erb +0 -17
- data/fixtures/rails_3_2_12_no_init/app/views/things/edit.html.erb +0 -6
- data/fixtures/rails_3_2_12_no_init/app/views/things/new.html.erb +0 -5
- data/fixtures/rails_3_2_12_no_init/app/views/things/show.html.erb +0 -5
- data/fixtures/rails_3_2_12_no_init/config/database.yml +0 -25
- data/fixtures/rails_3_2_12_no_init/config/environments/development.rb +0 -37
- data/fixtures/rails_3_2_12_no_init/config/environments/production.rb +0 -67
- data/fixtures/rails_3_2_12_no_init/config/initializers/backtrace_silencers.rb +0 -7
- data/fixtures/rails_3_2_12_no_init/config/initializers/inflections.rb +0 -15
- data/fixtures/rails_3_2_12_no_init/config/initializers/mime_types.rb +0 -5
- data/fixtures/rails_3_2_12_no_init/config/initializers/secret_token.rb +0 -7
- data/fixtures/rails_3_2_12_no_init/config/initializers/session_store.rb +0 -8
- data/fixtures/rails_3_2_12_no_init/config/initializers/wrap_parameters.rb +0 -14
- data/fixtures/rails_3_2_12_no_init/config/locales/en.yml +0 -5
- data/fixtures/rails_3_2_12_no_init/db/schema.rb +0 -16
- data/fixtures/rails_3_2_12_no_init/db/seeds.rb +0 -7
- data/lib/secure_headers/headers/content_security_policy/browser_strategy.rb +0 -78
- data/lib/secure_headers/headers/content_security_policy/firefox_browser_strategy.rb +0 -72
- data/lib/secure_headers/headers/content_security_policy/ie_browser_strategy.rb +0 -6
- data/lib/secure_headers/headers/content_security_policy/standard_browser_strategy.rb +0 -22
- data/spec/controllers/content_security_policy_controller_spec.rb +0 -74
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
module SecureHeaders
|
|
2
|
-
class ContentSecurityPolicy
|
|
3
|
-
class FirefoxBrowserStrategy < BrowserStrategy
|
|
4
|
-
def base_name
|
|
5
|
-
SecureHeaders::ContentSecurityPolicy::FIREFOX_CSP_HEADER_NAME
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def csp_header
|
|
9
|
-
SecureHeaders::ContentSecurityPolicy::FIREFOX_CSP_HEADER
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def directives
|
|
13
|
-
SecureHeaders::ContentSecurityPolicy::FIREFOX_DIRECTIVES
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def filter_unsupported_directives(config)
|
|
17
|
-
config = config.dup
|
|
18
|
-
config[:xhr_src] = config.delete(:connect_src) if config[:connect_src]
|
|
19
|
-
config
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def translate_inline_or_eval val
|
|
23
|
-
val == 'inline' ? 'inline-script' : 'eval-script'
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def build_impl_specific_directives(default)
|
|
27
|
-
build_firefox_specific_preamble(default) || ''
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def build_firefox_specific_preamble(default_src_value)
|
|
31
|
-
header_value = ''
|
|
32
|
-
header_value += "allow #{default_src_value.join(" ")}; " if default_src_value.any?
|
|
33
|
-
|
|
34
|
-
options_directive = build_options_directive
|
|
35
|
-
header_value += "options #{options_directive.join(" ")}; " if options_directive.any?
|
|
36
|
-
header_value
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# moves inline/eval values from script-src to options
|
|
40
|
-
# discards those values in the style-src directive
|
|
41
|
-
def build_options_directive
|
|
42
|
-
options_directive = []
|
|
43
|
-
config.each do |directive, val|
|
|
44
|
-
next if val.is_a?(String)
|
|
45
|
-
new_val = []
|
|
46
|
-
val.each do |token|
|
|
47
|
-
if ['inline-script', 'eval-script'].include?(token)
|
|
48
|
-
# Firefox does not support blocking inline styles ATM
|
|
49
|
-
# https://bugzilla.mozilla.org/show_bug.cgi?id=763879
|
|
50
|
-
unless directive?(directive, "style_src") || options_directive.include?(token)
|
|
51
|
-
options_directive << token
|
|
52
|
-
end
|
|
53
|
-
else
|
|
54
|
-
new_val << token
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
config[directive] = new_val
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
options_directive
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def directive? val, name
|
|
64
|
-
val.to_s.casecmp(name) == 0
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def normalize_reporting_endpoint?
|
|
68
|
-
true
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module SecureHeaders
|
|
2
|
-
class ContentSecurityPolicy
|
|
3
|
-
class StandardBrowserStrategy < BrowserStrategy
|
|
4
|
-
def base_name
|
|
5
|
-
if (browser.firefox? && browser.version.to_i >= 23) || (browser.chrome? && browser.version.to_i >= 25)
|
|
6
|
-
SecureHeaders::ContentSecurityPolicy::STANDARD_HEADER_NAME
|
|
7
|
-
else
|
|
8
|
-
SecureHeaders::ContentSecurityPolicy::WEBKIT_CSP_HEADER_NAME
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def add_missing_extension_values
|
|
13
|
-
directives.each do |directive|
|
|
14
|
-
next unless config[directive]
|
|
15
|
-
if !config[directive].include?('chrome-extension:')
|
|
16
|
-
config[directive] << 'chrome-extension:'
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe ContentSecurityPolicyController do
|
|
4
|
-
let(:params) {
|
|
5
|
-
{
|
|
6
|
-
"csp-report" => {
|
|
7
|
-
"document-uri" => "http://localhost:3001/csp","violated-directive" => "script-src 'none'",
|
|
8
|
-
"original-policy" => "default-src https://* 'unsafe-eval'; frame-src 'self'; img-src chrome-extension: https://*; report-uri http://localhost:3001/scribes/csp_report; script-src 'none'; style-src 'unsafe-inline' 'self';",
|
|
9
|
-
"blocked-uri" => "http://localhost:3001/stuff.js"
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe "#csp" do
|
|
15
|
-
let(:request) { double().as_null_object }
|
|
16
|
-
let(:endpoint) { "https://example.com" }
|
|
17
|
-
let(:secondary_endpoint) { "https://internal.example.com" }
|
|
18
|
-
|
|
19
|
-
before(:each) do
|
|
20
|
-
SecureHeaders::Configuration.stub(:csp).and_return({:report_uri => endpoint, :forward_endpoint => secondary_endpoint})
|
|
21
|
-
subject.should_receive :head
|
|
22
|
-
subject.stub(:params).and_return(params)
|
|
23
|
-
Net::HTTP.any_instance.stub(:request)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
context "delivery endpoint" do
|
|
27
|
-
it "posts over ssl" do
|
|
28
|
-
subject.should_receive(:use_ssl)
|
|
29
|
-
subject.scribe
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "posts over plain http" do
|
|
33
|
-
SecureHeaders::Configuration.stub(:csp).and_return(:report_uri => 'http://example.com')
|
|
34
|
-
subject.should_not_receive(:use_ssl)
|
|
35
|
-
subject.scribe
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "makes a POST request" do
|
|
40
|
-
Net::HTTP.stub(:new).and_return(request)
|
|
41
|
-
request.should_receive(:request).with(instance_of(::Net::HTTP::Post))
|
|
42
|
-
params.stub(:to_json)
|
|
43
|
-
subject.scribe
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "POSTs to the configured forward_endpoint" do
|
|
47
|
-
Net::HTTP::Post.should_receive(:new).with(secondary_endpoint).and_return(request)
|
|
48
|
-
subject.scribe
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "does not POST if there is no forwarder configured" do
|
|
52
|
-
SecureHeaders::Configuration.stub(:csp).and_return({})
|
|
53
|
-
Net::HTTP::Post.should_not_receive(:new)
|
|
54
|
-
subject.scribe
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "eliminates known phony CSP reports" do
|
|
58
|
-
SecureHeaders::Configuration.stub(:csp).and_return(:report_uri => nil)
|
|
59
|
-
Net::HTTP::Post.should_not_receive :new
|
|
60
|
-
subject.scribe
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it "logs errors when it cannot forward the CSP report" do
|
|
64
|
-
class Rails; def logger; end; end
|
|
65
|
-
logger = double(:repond_to? => true)
|
|
66
|
-
Rails.stub(:logger).and_return(logger)
|
|
67
|
-
|
|
68
|
-
SecureHeaders::Configuration.stub(:csp).and_raise(StandardError)
|
|
69
|
-
|
|
70
|
-
logger.should_receive(:warn)
|
|
71
|
-
subject.scribe
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|