secure_headers 2.3.0 → 3.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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +3 -0
- data/CHANGELOG.md +205 -0
- data/Gemfile +9 -10
- data/Guardfile +12 -0
- data/README.md +169 -301
- data/Rakefile +2 -36
- data/lib/secure_headers/configuration.rb +189 -0
- data/lib/secure_headers/headers/content_security_policy.rb +362 -213
- data/lib/secure_headers/headers/public_key_pins.rb +43 -58
- data/lib/secure_headers/headers/strict_transport_security.rb +21 -48
- data/lib/secure_headers/headers/x_content_type_options.rb +18 -32
- data/lib/secure_headers/headers/x_download_options.rb +18 -32
- data/lib/secure_headers/headers/x_frame_options.rb +24 -33
- data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +19 -33
- data/lib/secure_headers/headers/x_xss_protection.rb +17 -47
- data/lib/secure_headers/middleware.rb +15 -0
- data/lib/secure_headers/padrino.rb +1 -2
- data/lib/secure_headers/railtie.rb +9 -6
- data/lib/secure_headers/view_helper.rb +27 -44
- data/lib/secure_headers.rb +229 -162
- data/secure_headers.gemspec +7 -11
- data/spec/lib/secure_headers/configuration_spec.rb +80 -0
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +175 -262
- data/spec/lib/secure_headers/headers/public_key_pins_spec.rb +17 -17
- data/spec/lib/secure_headers/headers/strict_transport_security_spec.rb +11 -43
- data/spec/lib/secure_headers/headers/x_content_type_options_spec.rb +13 -18
- data/spec/lib/secure_headers/headers/x_download_options_spec.rb +13 -17
- data/spec/lib/secure_headers/headers/x_frame_options_spec.rb +15 -17
- data/spec/lib/secure_headers/headers/x_permitted_cross_domain_policies_spec.rb +22 -39
- data/spec/lib/secure_headers/headers/x_xss_protection_spec.rb +22 -30
- data/spec/lib/secure_headers/middleware_spec.rb +40 -0
- data/spec/lib/secure_headers_spec.rb +202 -326
- data/spec/spec_helper.rb +32 -28
- data/upgrading-to-3-0.md +37 -0
- metadata +14 -94
- data/fixtures/rails_3_2_12/.rspec +0 -1
- data/fixtures/rails_3_2_12/Gemfile +0 -6
- data/fixtures/rails_3_2_12/README.rdoc +0 -261
- data/fixtures/rails_3_2_12/Rakefile +0 -7
- data/fixtures/rails_3_2_12/app/controllers/application_controller.rb +0 -4
- data/fixtures/rails_3_2_12/app/controllers/other_things_controller.rb +0 -5
- data/fixtures/rails_3_2_12/app/controllers/things_controller.rb +0 -5
- data/fixtures/rails_3_2_12/app/models/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/app/views/layouts/application.html.erb +0 -11
- data/fixtures/rails_3_2_12/app/views/other_things/index.html.erb +0 -2
- data/fixtures/rails_3_2_12/app/views/things/index.html.erb +0 -1
- data/fixtures/rails_3_2_12/config/application.rb +0 -14
- data/fixtures/rails_3_2_12/config/boot.rb +0 -6
- data/fixtures/rails_3_2_12/config/environment.rb +0 -5
- data/fixtures/rails_3_2_12/config/environments/test.rb +0 -37
- data/fixtures/rails_3_2_12/config/initializers/secure_headers.rb +0 -17
- data/fixtures/rails_3_2_12/config/routes.rb +0 -4
- data/fixtures/rails_3_2_12/config/script_hashes.yml +0 -5
- data/fixtures/rails_3_2_12/config.ru +0 -7
- data/fixtures/rails_3_2_12/lib/assets/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/lib/tasks/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/log/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/spec/controllers/other_things_controller_spec.rb +0 -83
- data/fixtures/rails_3_2_12/spec/controllers/things_controller_spec.rb +0 -54
- data/fixtures/rails_3_2_12/spec/spec_helper.rb +0 -15
- data/fixtures/rails_3_2_12/vendor/assets/javascripts/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/vendor/assets/stylesheets/.gitkeep +0 -0
- data/fixtures/rails_3_2_12/vendor/plugins/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/.rspec +0 -1
- data/fixtures/rails_3_2_12_no_init/Gemfile +0 -5
- data/fixtures/rails_3_2_12_no_init/README.rdoc +0 -261
- data/fixtures/rails_3_2_12_no_init/Rakefile +0 -7
- data/fixtures/rails_3_2_12_no_init/app/controllers/application_controller.rb +0 -4
- data/fixtures/rails_3_2_12_no_init/app/controllers/other_things_controller.rb +0 -20
- data/fixtures/rails_3_2_12_no_init/app/controllers/things_controller.rb +0 -5
- data/fixtures/rails_3_2_12_no_init/app/models/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/app/views/layouts/application.html.erb +0 -12
- data/fixtures/rails_3_2_12_no_init/app/views/other_things/index.html.erb +0 -1
- data/fixtures/rails_3_2_12_no_init/app/views/things/index.html.erb +0 -0
- data/fixtures/rails_3_2_12_no_init/config/application.rb +0 -17
- data/fixtures/rails_3_2_12_no_init/config/boot.rb +0 -6
- data/fixtures/rails_3_2_12_no_init/config/environment.rb +0 -5
- data/fixtures/rails_3_2_12_no_init/config/environments/test.rb +0 -37
- data/fixtures/rails_3_2_12_no_init/config/routes.rb +0 -4
- data/fixtures/rails_3_2_12_no_init/config.ru +0 -4
- data/fixtures/rails_3_2_12_no_init/lib/assets/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/lib/tasks/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/log/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/spec/controllers/other_things_controller_spec.rb +0 -56
- data/fixtures/rails_3_2_12_no_init/spec/controllers/things_controller_spec.rb +0 -54
- data/fixtures/rails_3_2_12_no_init/spec/spec_helper.rb +0 -5
- data/fixtures/rails_3_2_12_no_init/vendor/assets/javascripts/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/vendor/assets/stylesheets/.gitkeep +0 -0
- data/fixtures/rails_3_2_12_no_init/vendor/plugins/.gitkeep +0 -0
- data/fixtures/rails_4_1_8/Gemfile +0 -5
- data/fixtures/rails_4_1_8/README.rdoc +0 -28
- data/fixtures/rails_4_1_8/Rakefile +0 -6
- data/fixtures/rails_4_1_8/app/controllers/application_controller.rb +0 -4
- data/fixtures/rails_4_1_8/app/controllers/concerns/.keep +0 -0
- data/fixtures/rails_4_1_8/app/controllers/other_things_controller.rb +0 -5
- data/fixtures/rails_4_1_8/app/controllers/things_controller.rb +0 -5
- 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 +0 -11
- data/fixtures/rails_4_1_8/app/views/other_things/index.html.erb +0 -2
- data/fixtures/rails_4_1_8/app/views/things/index.html.erb +0 -1
- data/fixtures/rails_4_1_8/config/application.rb +0 -15
- data/fixtures/rails_4_1_8/config/boot.rb +0 -4
- data/fixtures/rails_4_1_8/config/environment.rb +0 -5
- data/fixtures/rails_4_1_8/config/environments/test.rb +0 -10
- data/fixtures/rails_4_1_8/config/initializers/secure_headers.rb +0 -17
- data/fixtures/rails_4_1_8/config/routes.rb +0 -4
- data/fixtures/rails_4_1_8/config/script_hashes.yml +0 -5
- data/fixtures/rails_4_1_8/config/secrets.yml +0 -22
- data/fixtures/rails_4_1_8/config.ru +0 -4
- 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 +0 -83
- data/fixtures/rails_4_1_8/spec/controllers/things_controller_spec.rb +0 -59
- data/fixtures/rails_4_1_8/spec/spec_helper.rb +0 -15
- 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 +0 -7
- data/lib/secure_headers/header.rb +0 -5
- data/lib/secure_headers/headers/content_security_policy/script_hash_middleware.rb +0 -22
- data/lib/secure_headers/version.rb +0 -3
- data/lib/tasks/tasks.rake +0 -48
- data/spec/lib/secure_headers/headers/content_security_policy/script_hash_middleware_spec.rb +0 -47
|
@@ -2,60 +2,28 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module SecureHeaders
|
|
4
4
|
describe StrictTransportSecurity do
|
|
5
|
-
specify{ expect(StrictTransportSecurity.new.name).to eq("Strict-Transport-Security") }
|
|
6
|
-
|
|
7
5
|
describe "#value" do
|
|
8
|
-
specify { expect(StrictTransportSecurity.
|
|
9
|
-
specify { expect(StrictTransportSecurity.
|
|
10
|
-
specify { expect(StrictTransportSecurity.new(:max_age => '1234').value).to eq("max-age=1234")}
|
|
11
|
-
specify { expect(StrictTransportSecurity.new(:max_age => 1234).value).to eq("max-age=1234")}
|
|
12
|
-
specify { expect(StrictTransportSecurity.new(:max_age => HSTS_MAX_AGE, :include_subdomains => true).value).to eq("max-age=#{HSTS_MAX_AGE}; includeSubdomains")}
|
|
13
|
-
specify { expect(StrictTransportSecurity.new(:max_age => HSTS_MAX_AGE, :include_subdomains => true, :preload => true).value).to eq("max-age=#{HSTS_MAX_AGE}; includeSubdomains; preload")}
|
|
6
|
+
specify { expect(StrictTransportSecurity.make_header).to eq([StrictTransportSecurity::HEADER_NAME, StrictTransportSecurity::DEFAULT_VALUE]) }
|
|
7
|
+
specify { expect(StrictTransportSecurity.make_header("max-age=1234")).to eq([StrictTransportSecurity::HEADER_NAME, "max-age=1234"]) }
|
|
14
8
|
|
|
15
9
|
context "with an invalid configuration" do
|
|
16
|
-
context "with a hash argument" do
|
|
17
|
-
it "should allow string values for max-age" do
|
|
18
|
-
expect {
|
|
19
|
-
StrictTransportSecurity.new(:max_age => '1234')
|
|
20
|
-
}.not_to raise_error
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "should allow integer values for max-age" do
|
|
24
|
-
expect {
|
|
25
|
-
StrictTransportSecurity.new(:max_age => 1234)
|
|
26
|
-
}.not_to raise_error
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "raises an exception with an invalid max-age" do
|
|
30
|
-
expect {
|
|
31
|
-
StrictTransportSecurity.new(:max_age => 'abc123')
|
|
32
|
-
}.to raise_error(STSBuildError)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "raises an exception if max-age is not supplied" do
|
|
36
|
-
expect {
|
|
37
|
-
StrictTransportSecurity.new(:includeSubdomains => true)
|
|
38
|
-
}.to raise_error(STSBuildError)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
10
|
context "with a string argument" do
|
|
43
11
|
it "raises an exception with an invalid max-age" do
|
|
44
|
-
expect
|
|
45
|
-
StrictTransportSecurity.
|
|
46
|
-
|
|
12
|
+
expect do
|
|
13
|
+
StrictTransportSecurity.validate_config!('max-age=abc123')
|
|
14
|
+
end.to raise_error(STSConfigError)
|
|
47
15
|
end
|
|
48
16
|
|
|
49
17
|
it "raises an exception if max-age is not supplied" do
|
|
50
|
-
expect
|
|
51
|
-
StrictTransportSecurity.
|
|
52
|
-
|
|
18
|
+
expect do
|
|
19
|
+
StrictTransportSecurity.validate_config!('includeSubdomains')
|
|
20
|
+
end.to raise_error(STSConfigError)
|
|
53
21
|
end
|
|
54
22
|
|
|
55
23
|
it "raises an exception with an invalid format" do
|
|
56
|
-
expect
|
|
57
|
-
StrictTransportSecurity.
|
|
58
|
-
|
|
24
|
+
expect do
|
|
25
|
+
StrictTransportSecurity.validate_config!('max-age=123includeSubdomains')
|
|
26
|
+
end.to raise_error(STSConfigError)
|
|
59
27
|
end
|
|
60
28
|
end
|
|
61
29
|
end
|
|
@@ -1,33 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
1
3
|
module SecureHeaders
|
|
2
4
|
describe XContentTypeOptions do
|
|
3
|
-
specify{ expect(XContentTypeOptions.new.name).to eq("X-Content-Type-Options") }
|
|
4
|
-
|
|
5
5
|
describe "#value" do
|
|
6
|
-
specify { expect(XContentTypeOptions.
|
|
7
|
-
specify { expect(XContentTypeOptions.
|
|
8
|
-
specify { expect(XContentTypeOptions.new(:value => 'nosniff').value).to eq("nosniff")}
|
|
6
|
+
specify { expect(XContentTypeOptions.make_header).to eq([XContentTypeOptions::HEADER_NAME, XContentTypeOptions::DEFAULT_VALUE]) }
|
|
7
|
+
specify { expect(XContentTypeOptions.make_header("nosniff")).to eq([XContentTypeOptions::HEADER_NAME, "nosniff"]) }
|
|
9
8
|
|
|
10
9
|
context "invalid configuration values" do
|
|
11
10
|
it "accepts nosniff" do
|
|
12
|
-
expect
|
|
13
|
-
XContentTypeOptions.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
expect {
|
|
17
|
-
XContentTypeOptions.new(:value => "nosniff")
|
|
18
|
-
}.not_to raise_error
|
|
11
|
+
expect do
|
|
12
|
+
XContentTypeOptions.validate_config!("nosniff")
|
|
13
|
+
end.not_to raise_error
|
|
19
14
|
end
|
|
20
15
|
|
|
21
16
|
it "accepts nil" do
|
|
22
|
-
expect
|
|
23
|
-
XContentTypeOptions.
|
|
24
|
-
|
|
17
|
+
expect do
|
|
18
|
+
XContentTypeOptions.validate_config!(nil)
|
|
19
|
+
end.not_to raise_error
|
|
25
20
|
end
|
|
26
21
|
|
|
27
22
|
it "doesn't accept anything besides no-sniff" do
|
|
28
|
-
expect
|
|
29
|
-
XContentTypeOptions.
|
|
30
|
-
|
|
23
|
+
expect do
|
|
24
|
+
XContentTypeOptions.validate_config!("donkey")
|
|
25
|
+
end.to raise_error(XContentTypeOptionsConfigError)
|
|
31
26
|
end
|
|
32
27
|
end
|
|
33
28
|
end
|
|
@@ -1,31 +1,27 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
1
3
|
module SecureHeaders
|
|
2
4
|
describe XDownloadOptions do
|
|
3
|
-
specify { expect(XDownloadOptions.
|
|
4
|
-
specify { expect(XDownloadOptions.
|
|
5
|
-
specify { expect(XDownloadOptions.new('noopen').value).to eq('noopen')}
|
|
6
|
-
specify { expect(XDownloadOptions.new(:value => 'noopen').value).to eq('noopen') }
|
|
5
|
+
specify { expect(XDownloadOptions.make_header).to eq([XDownloadOptions::HEADER_NAME, XDownloadOptions::DEFAULT_VALUE]) }
|
|
6
|
+
specify { expect(XDownloadOptions.make_header('noopen')).to eq([XDownloadOptions::HEADER_NAME, 'noopen']) }
|
|
7
7
|
|
|
8
8
|
context "invalid configuration values" do
|
|
9
9
|
it "accepts noopen" do
|
|
10
|
-
expect
|
|
11
|
-
XDownloadOptions.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
expect {
|
|
15
|
-
XDownloadOptions.new(:value => "noopen")
|
|
16
|
-
}.not_to raise_error
|
|
10
|
+
expect do
|
|
11
|
+
XDownloadOptions.validate_config!("noopen")
|
|
12
|
+
end.not_to raise_error
|
|
17
13
|
end
|
|
18
14
|
|
|
19
15
|
it "accepts nil" do
|
|
20
|
-
expect
|
|
21
|
-
XDownloadOptions.
|
|
22
|
-
|
|
16
|
+
expect do
|
|
17
|
+
XDownloadOptions.validate_config!(nil)
|
|
18
|
+
end.not_to raise_error
|
|
23
19
|
end
|
|
24
20
|
|
|
25
21
|
it "doesn't accept anything besides noopen" do
|
|
26
|
-
expect
|
|
27
|
-
XDownloadOptions.
|
|
28
|
-
|
|
22
|
+
expect do
|
|
23
|
+
XDownloadOptions.validate_config!("open")
|
|
24
|
+
end.to raise_error(XDOConfigError)
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
end
|
|
@@ -2,34 +2,32 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module SecureHeaders
|
|
4
4
|
describe XFrameOptions do
|
|
5
|
-
specify{ expect(XFrameOptions.new.name).to eq("X-Frame-Options") }
|
|
6
|
-
|
|
7
5
|
describe "#value" do
|
|
8
|
-
specify { expect(XFrameOptions.
|
|
9
|
-
specify { expect(XFrameOptions.
|
|
10
|
-
specify { expect(XFrameOptions.new(:value => 'DENY').value).to eq("DENY")}
|
|
6
|
+
specify { expect(XFrameOptions.make_header).to eq([XFrameOptions::HEADER_NAME, XFrameOptions::DEFAULT_VALUE]) }
|
|
7
|
+
specify { expect(XFrameOptions.make_header("DENY")).to eq([XFrameOptions::HEADER_NAME, "DENY"]) }
|
|
11
8
|
|
|
12
9
|
context "with invalid configuration" do
|
|
13
10
|
it "allows SAMEORIGIN" do
|
|
14
|
-
expect
|
|
15
|
-
XFrameOptions.
|
|
16
|
-
|
|
11
|
+
expect do
|
|
12
|
+
XFrameOptions.validate_config!("SAMEORIGIN")
|
|
13
|
+
end.not_to raise_error
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
it "allows DENY" do
|
|
20
|
-
expect
|
|
21
|
-
XFrameOptions.
|
|
22
|
-
|
|
17
|
+
expect do
|
|
18
|
+
XFrameOptions.validate_config!("DENY")
|
|
19
|
+
end.not_to raise_error
|
|
20
|
+
end
|
|
23
21
|
|
|
24
22
|
it "allows ALLOW-FROM*" do
|
|
25
|
-
expect
|
|
26
|
-
XFrameOptions.
|
|
27
|
-
|
|
23
|
+
expect do
|
|
24
|
+
XFrameOptions.validate_config!("ALLOW-FROM: example.com")
|
|
25
|
+
end.not_to raise_error
|
|
28
26
|
end
|
|
29
27
|
it "does not allow garbage" do
|
|
30
|
-
expect
|
|
31
|
-
XFrameOptions.
|
|
32
|
-
|
|
28
|
+
expect do
|
|
29
|
+
XFrameOptions.validate_config!("I like turtles")
|
|
30
|
+
end.to raise_error(XFOConfigError)
|
|
33
31
|
end
|
|
34
32
|
end
|
|
35
33
|
end
|
|
@@ -1,63 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
1
3
|
module SecureHeaders
|
|
2
4
|
describe XPermittedCrossDomainPolicies do
|
|
3
|
-
specify { expect(XPermittedCrossDomainPolicies.
|
|
4
|
-
specify { expect(XPermittedCrossDomainPolicies.
|
|
5
|
-
specify { expect(XPermittedCrossDomainPolicies.new('master-only').value).to eq('master-only')}
|
|
6
|
-
specify { expect(XPermittedCrossDomainPolicies.new(:value => 'master-only').value).to eq('master-only') }
|
|
5
|
+
specify { expect(XPermittedCrossDomainPolicies.make_header).to eq([XPermittedCrossDomainPolicies::HEADER_NAME, "none"]) }
|
|
6
|
+
specify { expect(XPermittedCrossDomainPolicies.make_header('master-only')).to eq([XPermittedCrossDomainPolicies::HEADER_NAME, 'master-only']) }
|
|
7
7
|
|
|
8
8
|
context "valid configuration values" do
|
|
9
9
|
it "accepts 'all'" do
|
|
10
|
-
expect
|
|
11
|
-
XPermittedCrossDomainPolicies.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
expect {
|
|
15
|
-
XPermittedCrossDomainPolicies.new(:value => "all")
|
|
16
|
-
}.not_to raise_error
|
|
10
|
+
expect do
|
|
11
|
+
XPermittedCrossDomainPolicies.validate_config!("all")
|
|
12
|
+
end.not_to raise_error
|
|
17
13
|
end
|
|
18
14
|
|
|
19
15
|
it "accepts 'by-ftp-filename'" do
|
|
20
|
-
expect
|
|
21
|
-
XPermittedCrossDomainPolicies.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
expect {
|
|
25
|
-
XPermittedCrossDomainPolicies.new(:value => "by-ftp-filename")
|
|
26
|
-
}.not_to raise_error
|
|
16
|
+
expect do
|
|
17
|
+
XPermittedCrossDomainPolicies.validate_config!("by-ftp-filename")
|
|
18
|
+
end.not_to raise_error
|
|
27
19
|
end
|
|
28
20
|
|
|
29
21
|
it "accepts 'by-content-type'" do
|
|
30
|
-
expect
|
|
31
|
-
XPermittedCrossDomainPolicies.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
expect {
|
|
35
|
-
XPermittedCrossDomainPolicies.new(:value => "by-content-type")
|
|
36
|
-
}.not_to raise_error
|
|
22
|
+
expect do
|
|
23
|
+
XPermittedCrossDomainPolicies.validate_config!("by-content-type")
|
|
24
|
+
end.not_to raise_error
|
|
37
25
|
end
|
|
38
26
|
it "accepts 'master-only'" do
|
|
39
|
-
expect
|
|
40
|
-
XPermittedCrossDomainPolicies.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
expect {
|
|
44
|
-
XPermittedCrossDomainPolicies.new(:value => "master-only")
|
|
45
|
-
}.not_to raise_error
|
|
27
|
+
expect do
|
|
28
|
+
XPermittedCrossDomainPolicies.validate_config!("master-only")
|
|
29
|
+
end.not_to raise_error
|
|
46
30
|
end
|
|
47
31
|
|
|
48
32
|
it "accepts nil" do
|
|
49
|
-
expect
|
|
50
|
-
XPermittedCrossDomainPolicies.
|
|
51
|
-
|
|
33
|
+
expect do
|
|
34
|
+
XPermittedCrossDomainPolicies.validate_config!(nil)
|
|
35
|
+
end.not_to raise_error
|
|
52
36
|
end
|
|
53
37
|
end
|
|
54
38
|
|
|
55
39
|
context 'invlaid configuration values' do
|
|
56
|
-
|
|
57
40
|
it "doesn't accept invalid values" do
|
|
58
|
-
expect
|
|
59
|
-
XPermittedCrossDomainPolicies.
|
|
60
|
-
|
|
41
|
+
expect do
|
|
42
|
+
XPermittedCrossDomainPolicies.validate_config!("open")
|
|
43
|
+
end.to raise_error(XPCDPConfigError)
|
|
61
44
|
end
|
|
62
45
|
end
|
|
63
46
|
end
|
|
@@ -1,54 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
1
3
|
module SecureHeaders
|
|
2
4
|
describe XXssProtection do
|
|
3
|
-
specify { expect(XXssProtection.
|
|
4
|
-
specify { expect(XXssProtection.
|
|
5
|
-
specify { expect(XXssProtection.new("0").value).to eq("0")}
|
|
6
|
-
specify { expect(XXssProtection.new(:value => 1, :mode => 'block').value).to eq('1; mode=block') }
|
|
7
|
-
specify { expect(XXssProtection.new(:value => 1, :mode => 'block', :report_uri => 'https://www.secure.com/reports').value).to eq('1; mode=block; report=https://www.secure.com/reports') }
|
|
5
|
+
specify { expect(XXssProtection.make_header).to eq([XXssProtection::HEADER_NAME, XXssProtection::DEFAULT_VALUE]) }
|
|
6
|
+
specify { expect(XXssProtection.make_header("1; mode=block; report=https://www.secure.com/reports")).to eq([XXssProtection::HEADER_NAME, '1; mode=block; report=https://www.secure.com/reports']) }
|
|
8
7
|
|
|
9
8
|
context "with invalid configuration" do
|
|
10
9
|
it "should raise an error when providing a string that is not valid" do
|
|
11
|
-
expect
|
|
12
|
-
XXssProtection.
|
|
13
|
-
|
|
10
|
+
expect do
|
|
11
|
+
XXssProtection.validate_config!("asdf")
|
|
12
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
14
13
|
|
|
15
|
-
expect
|
|
16
|
-
XXssProtection.
|
|
17
|
-
|
|
14
|
+
expect do
|
|
15
|
+
XXssProtection.validate_config!("asdf; mode=donkey")
|
|
16
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
context "when using a hash value" do
|
|
21
20
|
it "should allow string values ('1' or '0' are the only valid strings)" do
|
|
22
|
-
expect
|
|
23
|
-
XXssProtection.
|
|
24
|
-
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "should allow integer values (1 or 0 are the only valid integers)" do
|
|
28
|
-
expect {
|
|
29
|
-
XXssProtection.new(:value => 1)
|
|
30
|
-
}.not_to raise_error
|
|
21
|
+
expect do
|
|
22
|
+
XXssProtection.validate_config!('1')
|
|
23
|
+
end.not_to raise_error
|
|
31
24
|
end
|
|
32
25
|
|
|
33
26
|
it "should raise an error if no value key is supplied" do
|
|
34
|
-
expect
|
|
35
|
-
XXssProtection.
|
|
36
|
-
|
|
27
|
+
expect do
|
|
28
|
+
XXssProtection.validate_config!("mode=block")
|
|
29
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
37
30
|
end
|
|
38
31
|
|
|
39
32
|
it "should raise an error if an invalid key is supplied" do
|
|
40
|
-
expect
|
|
41
|
-
XXssProtection.
|
|
42
|
-
|
|
33
|
+
expect do
|
|
34
|
+
XXssProtection.validate_config!("123")
|
|
35
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
43
36
|
end
|
|
44
37
|
|
|
45
38
|
it "should raise an error if mode != block" do
|
|
46
|
-
expect
|
|
47
|
-
XXssProtection.
|
|
48
|
-
|
|
39
|
+
expect do
|
|
40
|
+
XXssProtection.validate_config!("1; mode=donkey")
|
|
41
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
49
42
|
end
|
|
50
43
|
end
|
|
51
|
-
|
|
52
44
|
end
|
|
53
45
|
end
|
|
54
46
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module SecureHeaders
|
|
4
|
+
describe Middleware do
|
|
5
|
+
let(:app) { ->(env) { [200, env, "app"] } }
|
|
6
|
+
|
|
7
|
+
let :middleware do
|
|
8
|
+
Middleware.new(app)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before(:each) do
|
|
12
|
+
reset_config
|
|
13
|
+
Configuration.default do |config|
|
|
14
|
+
# use all default provided by the library
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "sets the headers" do
|
|
19
|
+
_, env = middleware.call(Rack::MockRequest.env_for("https://looocalhost", {}))
|
|
20
|
+
expect_default_values(env)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "respects overrides" do
|
|
24
|
+
request = Rack::Request.new("HTTP_X_FORWARDED_SSL" => "on")
|
|
25
|
+
SecureHeaders.override_x_frame_options(request, "DENY")
|
|
26
|
+
_, env = middleware.call request.env
|
|
27
|
+
expect(env[XFrameOptions::HEADER_NAME]).to eq("DENY")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "uses named overrides" do
|
|
31
|
+
Configuration.override("my_custom_config") do |config|
|
|
32
|
+
config.csp[:script_src] = %w(example.org)
|
|
33
|
+
end
|
|
34
|
+
request = Rack::Request.new({})
|
|
35
|
+
SecureHeaders.use_secure_headers_override(request, "my_custom_config")
|
|
36
|
+
_, env = middleware.call request.env
|
|
37
|
+
expect(env[CSP::HEADER_NAME]).to match("example.org")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|