Skip to content

Commit 9b79253

Browse files
authored
Merge pull request #137 from rails/flavorjones-prevent-select-style-combination_v1.4.x
prevent combination of `select` and `style` tags with the HTML4 parser
2 parents 045774a + 45a5c10 commit 9b79253

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/rails/html/sanitizer.rb

+18-1
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,25 @@ def sanitize_css(style_string)
141141

142142
private
143143

144+
def loofah_using_html5?
145+
# future-proofing, see https://github.com/flavorjones/loofah/pull/239
146+
Loofah.respond_to?(:html5_mode?) && Loofah.html5_mode?
147+
end
148+
149+
def remove_safelist_tag_combinations(tags)
150+
if !loofah_using_html5? && tags.include?("select") && tags.include?("style")
151+
warn("WARNING: #{self.class}: removing 'style' from safelist, should not be combined with 'select'")
152+
tags.delete("style")
153+
end
154+
tags
155+
end
156+
144157
def allowed_tags(options)
145-
options[:tags] || self.class.allowed_tags
158+
if options[:tags]
159+
remove_safelist_tag_combinations(options[:tags])
160+
else
161+
self.class.allowed_tags
162+
end
146163
end
147164

148165
def allowed_attributes(options)

test/sanitizer_test.rb

+23
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,25 @@ def test_exclude_node_type_comment
581581
assert_equal("<div>text</div><b>text</b>", safe_list_sanitize("<div>text</div><!-- comment --><b>text</b>"))
582582
end
583583

584+
def test_disallow_the_dangerous_safelist_combination_of_select_and_style
585+
input = "<select><style><script>alert(1)</script></style></select>"
586+
tags = ["select", "style"]
587+
warning = /WARNING: Rails::Html::SafeListSanitizer: removing 'style' from safelist/
588+
sanitized = nil
589+
invocation = Proc.new { sanitized = safe_list_sanitize(input, tags: tags) }
590+
591+
if html5_mode?
592+
# if Loofah is using an HTML5 parser,
593+
# then "style" should be removed by the parser as an invalid child of "select"
594+
assert_silent(&invocation)
595+
else
596+
# if Loofah is using an HTML4 parser,
597+
# then SafeListSanitizer should remove "style" from the safelist
598+
assert_output(nil, warning, &invocation)
599+
end
600+
refute_includes(sanitized, "style")
601+
end
602+
584603
protected
585604

586605
def xpath_sanitize(input, options = {})
@@ -641,4 +660,8 @@ def convert_to_css_hex(string, escape_parens=false)
641660
def libxml_2_9_14_recovery?
642661
Nokogiri.method(:uses_libxml?).arity == -1 && Nokogiri.uses_libxml?(">= 2.9.14")
643662
end
663+
664+
def html5_mode?
665+
::Loofah.respond_to?(:html5_mode?) && ::Loofah.html5_mode?
666+
end
644667
end

0 commit comments

Comments
 (0)