Skip to content

Commit 4dffb23

Browse files
committed
Add CSP config flag to preserve host source schemes
Before this change, all schemes were stripped from host sources. This is because modern browsers know that on an HTTPS resource, only HTTPS is allowed but on HTTP resources, both HTTP and HTTPS are allowed. Safari on the other hand doesn't support this. In an ideal world, all local development would be over HTTPS and there would never be a need to serve/load HTTP resources. Adding :preserve_schemes (defaults to false) unfortunately also allows mixed content. i.e. If you are on an HTTPS resource, but you've whitelisted an HTTP resource you have allowed mixed content.
1 parent f23a66f commit 4dffb23

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ def initialize(config = nil, user_agent = OTHER)
275275
else
276276
UserAgent.parse(user_agent)
277277
end
278-
@report_only = !!@config[:report_only]
278+
@report_only = @config[:report_only]
279+
@preserve_schemes = @config[:preserve_schemes]
279280
@script_nonce = @config[:script_nonce]
280281
@style_nonce = @config[:style_nonce]
281282
end
@@ -345,9 +346,12 @@ def build_directive(directive_name)
345346
source_list.reject! { |value| value == NONE } if source_list.length > 1
346347

347348
# remove schemes and dedup source expressions
348-
source_list = strip_source_schemes(source_list) unless directive_name == REPORT_URI
349+
unless directive_name == REPORT_URI || @preserve_schemes
350+
source_list = strip_source_schemes(source_list)
351+
end
349352
dedup_source_list(source_list).join(" ")
350353
end
354+
351355
[symbol_to_hyphen_case(directive_name), value].join(" ")
352356
end
353357

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ module SecureHeaders
138138
expect(csp.value).to eq("default-src https:; report-uri https://example.org")
139139
end
140140

141+
it "does not remove schemes when :preserve_schemes is true" do
142+
csp = ContentSecurityPolicy.new(default_src: %w(https://example.org), :preserve_schemes => true)
143+
expect(csp.value).to eq("default-src https://example.org")
144+
end
145+
141146
it "removes nil from source lists" do
142147
csp = ContentSecurityPolicy.new(default_src: ["https://example.org", nil])
143148
expect(csp.value).to eq("default-src example.org")

0 commit comments

Comments
 (0)