Skip to content

Commit 082f6c8

Browse files
committed
Merge pull request #224 from twitter/handle-non-default-sources
Handle policy merges when directives do not inherit from default-src
2 parents b6b1fb4 + 248dcf2 commit 082f6c8

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ class ContentSecurityPolicy
5555
FRAME_ANCESTORS = :frame_ancestors
5656
PLUGIN_TYPES = :plugin_types
5757

58+
# These are directives that do not inherit the default-src value. This is
59+
# useful when calling #combine_policies.
60+
NON_DEFAULT_SOURCES = [
61+
BASE_URI,
62+
FORM_ACTION,
63+
FRAME_ANCESTORS,
64+
PLUGIN_TYPES,
65+
REPORT_URI
66+
]
67+
5868
DIRECTIVES_2_0 = [
5969
DIRECTIVES_1_0,
6070
BASE_URI,
@@ -214,7 +224,7 @@ def combine_policies(original, additions)
214224

215225
# in case we would be appending to an empty directive, fill it with the default-src value
216226
additions.keys.each do |directive|
217-
unless original[directive] || !source_list?(directive)
227+
unless original[directive] || !source_list?(directive) || NON_DEFAULT_SOURCES.include?(directive)
218228
original[directive] = original[:default_src]
219229
end
220230
end

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,29 @@ module SecureHeaders
124124
report_only: false
125125
}.freeze
126126
end
127-
combined_config = CSP.combine_policies(Configuration.get.csp, report_uri: %w(https://report-uri.io/asdf))
128-
expect(combined_config[:report_uri]).to_not be_nil
127+
report_uri = "https://report-uri.io/asdf"
128+
combined_config = CSP.combine_policies(Configuration.get.csp, report_uri: [report_uri])
129+
csp = ContentSecurityPolicy.new(combined_config, USER_AGENTS[:firefox])
130+
expect(csp.value).to include("report-uri #{report_uri}")
131+
end
132+
133+
it "does not combine the default-src value for directives that don't fall back to default sources" do
134+
Configuration.default do |config|
135+
config.csp = {
136+
default_src: %w('self'),
137+
report_only: false
138+
}.freeze
139+
end
140+
non_default_source_additions = CSP::NON_DEFAULT_SOURCES.each_with_object({}) do |directive, hash|
141+
hash[directive] = %w("http://example.org)
142+
end
143+
combined_config = CSP.combine_policies(Configuration.get.csp, non_default_source_additions)
144+
145+
CSP::NON_DEFAULT_SOURCES.each do |directive|
146+
expect(combined_config[directive]).to eq(%w("http://example.org))
147+
end
148+
149+
ContentSecurityPolicy.new(combined_config, USER_AGENTS[:firefox]).value
129150
end
130151

131152
it "overrides the report_only flag" do

0 commit comments

Comments
 (0)