secure_headers 2.5.3 → 3.0.0.pre
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/.travis.yml +2 -1
- data/Gemfile +9 -16
- data/README.md +154 -331
- data/Rakefile +2 -36
- data/lib/secure_headers/configuration.rb +189 -0
- data/lib/secure_headers/headers/content_security_policy.rb +341 -254
- data/lib/secure_headers/headers/public_key_pins.rb +43 -58
- data/lib/secure_headers/headers/strict_transport_security.rb +21 -49
- data/lib/secure_headers/headers/x_content_type_options.rb +18 -33
- data/lib/secure_headers/headers/x_download_options.rb +18 -33
- data/lib/secure_headers/headers/x_frame_options.rb +24 -34
- data/lib/secure_headers/headers/x_permitted_cross_domain_policies.rb +19 -34
- data/lib/secure_headers/headers/x_xss_protection.rb +17 -48
- 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 -43
- data/lib/secure_headers.rb +254 -61
- data/secure_headers.gemspec +7 -12
- data/spec/lib/secure_headers/configuration_spec.rb +80 -0
- data/spec/lib/secure_headers/headers/content_security_policy_spec.rb +111 -276
- 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 +11 -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 +20 -30
- data/spec/lib/secure_headers/middleware_spec.rb +40 -0
- data/spec/lib/secure_headers_spec.rb +201 -339
- data/spec/spec_helper.rb +30 -30
- data/upgrading-to-3-0.md +35 -0
- metadata +14 -100
- data/fixtures/rails_3_2_22/.rspec +0 -1
- data/fixtures/rails_3_2_22/Gemfile +0 -6
- data/fixtures/rails_3_2_22/README.rdoc +0 -261
- data/fixtures/rails_3_2_22/Rakefile +0 -7
- data/fixtures/rails_3_2_22/app/controllers/application_controller.rb +0 -4
- data/fixtures/rails_3_2_22/app/controllers/other_things_controller.rb +0 -5
- data/fixtures/rails_3_2_22/app/controllers/things_controller.rb +0 -5
- data/fixtures/rails_3_2_22/app/models/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/app/views/layouts/application.html.erb +0 -11
- data/fixtures/rails_3_2_22/app/views/other_things/index.html.erb +0 -2
- data/fixtures/rails_3_2_22/app/views/things/index.html.erb +0 -1
- data/fixtures/rails_3_2_22/config/application.rb +0 -14
- data/fixtures/rails_3_2_22/config/boot.rb +0 -6
- data/fixtures/rails_3_2_22/config/environment.rb +0 -5
- data/fixtures/rails_3_2_22/config/environments/test.rb +0 -37
- data/fixtures/rails_3_2_22/config/initializers/secure_headers.rb +0 -16
- data/fixtures/rails_3_2_22/config/routes.rb +0 -4
- data/fixtures/rails_3_2_22/config/script_hashes.yml +0 -5
- data/fixtures/rails_3_2_22/config.ru +0 -7
- data/fixtures/rails_3_2_22/lib/assets/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/lib/tasks/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/log/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/spec/controllers/other_things_controller_spec.rb +0 -83
- data/fixtures/rails_3_2_22/spec/controllers/things_controller_spec.rb +0 -54
- data/fixtures/rails_3_2_22/spec/spec_helper.rb +0 -15
- data/fixtures/rails_3_2_22/vendor/assets/javascripts/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/vendor/assets/stylesheets/.gitkeep +0 -0
- data/fixtures/rails_3_2_22/vendor/plugins/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/.rspec +0 -1
- data/fixtures/rails_3_2_22_no_init/Gemfile +0 -6
- data/fixtures/rails_3_2_22_no_init/README.rdoc +0 -261
- data/fixtures/rails_3_2_22_no_init/Rakefile +0 -7
- data/fixtures/rails_3_2_22_no_init/app/controllers/application_controller.rb +0 -4
- data/fixtures/rails_3_2_22_no_init/app/controllers/other_things_controller.rb +0 -20
- data/fixtures/rails_3_2_22_no_init/app/controllers/things_controller.rb +0 -5
- data/fixtures/rails_3_2_22_no_init/app/models/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/app/views/layouts/application.html.erb +0 -12
- data/fixtures/rails_3_2_22_no_init/app/views/other_things/index.html.erb +0 -1
- data/fixtures/rails_3_2_22_no_init/app/views/things/index.html.erb +0 -0
- data/fixtures/rails_3_2_22_no_init/config/application.rb +0 -17
- data/fixtures/rails_3_2_22_no_init/config/boot.rb +0 -6
- data/fixtures/rails_3_2_22_no_init/config/environment.rb +0 -5
- data/fixtures/rails_3_2_22_no_init/config/environments/test.rb +0 -37
- data/fixtures/rails_3_2_22_no_init/config/routes.rb +0 -4
- data/fixtures/rails_3_2_22_no_init/config.ru +0 -4
- data/fixtures/rails_3_2_22_no_init/lib/assets/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/lib/tasks/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/log/.gitkeep +0 -0
- data/fixtures/rails_3_2_22_no_init/spec/controllers/other_things_controller_spec.rb +0 -56
- data/fixtures/rails_3_2_22_no_init/spec/controllers/things_controller_spec.rb +0 -54
- data/fixtures/rails_3_2_22_no_init/spec/spec_helper.rb +0 -5
- data/fixtures/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/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 -16
- 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/controller_extension.rb +0 -158
- 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 -46
|
@@ -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
|
|
@@ -2,55 +2,45 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module SecureHeaders
|
|
4
4
|
describe XXssProtection do
|
|
5
|
-
specify { expect(XXssProtection.
|
|
6
|
-
specify { expect(XXssProtection.
|
|
7
|
-
specify { expect(XXssProtection.new("0").value).to eq("0")}
|
|
8
|
-
specify { expect(XXssProtection.new(:value => 1, :mode => 'block').value).to eq('1; mode=block') }
|
|
9
|
-
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']) }
|
|
10
7
|
|
|
11
8
|
context "with invalid configuration" do
|
|
12
9
|
it "should raise an error when providing a string that is not valid" do
|
|
13
|
-
expect
|
|
14
|
-
XXssProtection.
|
|
15
|
-
|
|
10
|
+
expect do
|
|
11
|
+
XXssProtection.validate_config!("asdf")
|
|
12
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
16
13
|
|
|
17
|
-
expect
|
|
18
|
-
XXssProtection.
|
|
19
|
-
|
|
14
|
+
expect do
|
|
15
|
+
XXssProtection.validate_config!("asdf; mode=donkey")
|
|
16
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
20
17
|
end
|
|
21
18
|
|
|
22
19
|
context "when using a hash value" do
|
|
23
20
|
it "should allow string values ('1' or '0' are the only valid strings)" do
|
|
24
|
-
expect
|
|
25
|
-
XXssProtection.
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "should allow integer values (1 or 0 are the only valid integers)" do
|
|
30
|
-
expect {
|
|
31
|
-
XXssProtection.new(:value => 1)
|
|
32
|
-
}.not_to raise_error
|
|
21
|
+
expect do
|
|
22
|
+
XXssProtection.validate_config!('1')
|
|
23
|
+
end.not_to raise_error
|
|
33
24
|
end
|
|
34
25
|
|
|
35
26
|
it "should raise an error if no value key is supplied" do
|
|
36
|
-
expect
|
|
37
|
-
XXssProtection.
|
|
38
|
-
|
|
27
|
+
expect do
|
|
28
|
+
XXssProtection.validate_config!("mode=block")
|
|
29
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
39
30
|
end
|
|
40
31
|
|
|
41
32
|
it "should raise an error if an invalid key is supplied" do
|
|
42
|
-
expect
|
|
43
|
-
XXssProtection.
|
|
44
|
-
|
|
33
|
+
expect do
|
|
34
|
+
XXssProtection.validate_config!("123")
|
|
35
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
45
36
|
end
|
|
46
37
|
|
|
47
38
|
it "should raise an error if mode != block" do
|
|
48
|
-
expect
|
|
49
|
-
XXssProtection.
|
|
50
|
-
|
|
39
|
+
expect do
|
|
40
|
+
XXssProtection.validate_config!("1; mode=donkey")
|
|
41
|
+
end.to raise_error(XXssProtectionConfigError)
|
|
51
42
|
end
|
|
52
43
|
end
|
|
53
|
-
|
|
54
44
|
end
|
|
55
45
|
end
|
|
56
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
|