Skip to content

Commit 6e38cb4

Browse files
authored
Merge pull request #419 from twitter/escape-semi-colons
Escape semi colons in directive source lists
2 parents 86c762a + eed6c16 commit 6e38cb4

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

lib/secure_headers/configuration.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ def deep_copy_if_hash(value)
126126
# The list of attributes that must respond to a `make_header` method
127127
HEADERABLE_ATTRIBUTES = (CONFIG_ATTRIBUTES - [:cookies]).freeze
128128

129-
attr_accessor(*CONFIG_ATTRIBUTES_TO_HEADER_CLASSES.keys)
129+
attr_writer(*(CONFIG_ATTRIBUTES_TO_HEADER_CLASSES.reject { |key| [:csp, :csp_report_only].include?(key) }.keys))
130+
131+
attr_reader(*(CONFIG_ATTRIBUTES_TO_HEADER_CLASSES.keys))
130132

131133
@script_hashes = nil
132134
@style_hashes = nil

lib/secure_headers/headers/content_security_policy.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,15 @@ def build_media_type_list_directive(directive)
103103
# Returns a string representing a directive.
104104
def build_source_list_directive(directive)
105105
source_list = @config.directive_value(directive)
106-
107106
if source_list != OPT_OUT && source_list && source_list.any?
108-
normalized_source_list = minify_source_list(directive, source_list)
109-
[symbol_to_hyphen_case(directive), normalized_source_list].join(" ")
107+
minified_source_list = minify_source_list(directive, source_list).join(" ")
108+
109+
if minified_source_list.include?(";")
110+
Kernel.warn("#{directive} contains a ; in '#{minified_source_list}' which will raise an error in future versions. It has been replaced with a blank space.")
111+
end
112+
113+
escaped_source_list = minified_source_list.gsub(";", " ")
114+
[symbol_to_hyphen_case(directive), escaped_source_list].join(" ").strip
110115
end
111116
end
112117

spec/lib/secure_headers/headers/content_security_policy_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ module SecureHeaders
2828
expect(ContentSecurityPolicy.new.value).to eq("default-src https:; form-action 'self'; img-src https: data: 'self'; object-src 'none'; script-src https:; style-src 'self' 'unsafe-inline' https:")
2929
end
3030

31+
it "deprecates and escapes semicolons in directive source lists" do
32+
expect(Kernel).to receive(:warn).with("frame_ancestors contains a ; in 'google.com;script-src *;.;' which will raise an error in future versions. It has been replaced with a blank space.")
33+
expect(ContentSecurityPolicy.new(frame_ancestors: %w(https://google.com;script-src https://*;.;)).value).to eq("frame-ancestors google.com script-src * .")
34+
end
35+
3136
it "discards 'none' values if any other source expressions are present" do
3237
csp = ContentSecurityPolicy.new(default_opts.merge(child_src: %w('self' 'none')))
3338
expect(csp.value).not_to include("'none'")

0 commit comments

Comments
 (0)