Skip to content

Commit bb6dfcb

Browse files
committed
fix: use Loofah's scrub_uri_attribute method
which correctly sanitizes data URL mediatypes
1 parent 56c61c0 commit bb6dfcb

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

lib/rails/html/scrubbers.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,7 @@ def scrub_attribute(node, attr_node)
140140
end
141141

142142
if Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name)
143-
# this block lifted nearly verbatim from HTML5 sanitization
144-
val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(Loofah::HTML5::Scrub::CONTROL_CHARACTERS,'').downcase
145-
if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && ! Loofah::HTML5::SafeList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR)[0])
146-
attr_node.remove
147-
end
143+
return if Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
148144
end
149145

150146
if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)

test/sanitizer_test.rb

+50
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,56 @@ def test_disallow_the_dangerous_safelist_combination_of_select_and_style
606606
refute_includes(sanitized, "style")
607607
end
608608

609+
%w[text/plain text/css image/png image/gif image/jpeg].each do |mediatype|
610+
define_method "test_mediatype_#{mediatype}_allowed" do
611+
input = %Q(<img src="data:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
612+
expected = input
613+
actual = safe_list_sanitize(input)
614+
assert_equal(expected, actual)
615+
616+
input = %Q(<img src="DATA:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
617+
expected = input
618+
actual = safe_list_sanitize(input)
619+
assert_equal(expected, actual)
620+
end
621+
end
622+
623+
def test_mediatype_text_html_disallowed
624+
input = %q(<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
625+
expected = %q(<img>)
626+
actual = safe_list_sanitize(input)
627+
assert_equal(expected, actual)
628+
629+
input = %q(<img src="DATA:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
630+
expected = %q(<img>)
631+
actual = safe_list_sanitize(input)
632+
assert_equal(expected, actual)
633+
end
634+
635+
def test_mediatype_image_svg_xml_disallowed
636+
input = %q(<img src="data:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
637+
expected = %q(<img>)
638+
actual = safe_list_sanitize(input)
639+
assert_equal(expected, actual)
640+
641+
input = %q(<img src="DATA:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
642+
expected = %q(<img>)
643+
actual = safe_list_sanitize(input)
644+
assert_equal(expected, actual)
645+
end
646+
647+
def test_mediatype_other_disallowed
648+
input = %q(<a href="data:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
649+
expected = %q(<a>foo</a>)
650+
actual = safe_list_sanitize(input)
651+
assert_equal(expected, actual)
652+
653+
input = %q(<a href="DATA:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
654+
expected = %q(<a>foo</a>)
655+
actual = safe_list_sanitize(input)
656+
assert_equal(expected, actual)
657+
end
658+
609659
def test_scrubbing_svg_attr_values_that_allow_ref
610660
input = %Q(<div fill="yellow url(http://bad.com/) #fff">hey</div>)
611661
expected = %Q(<div fill="yellow #fff">hey</div>)

0 commit comments

Comments
 (0)