Skip to content

Commit

Permalink
fix: use Loofah's scrub_uri_attribute method
Browse files Browse the repository at this point in the history
which correctly sanitizes data URL mediatypes
  • Loading branch information
flavorjones committed Dec 11, 2022
1 parent f0e3347 commit d1223a2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
6 changes: 1 addition & 5 deletions lib/rails/html/scrubbers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,7 @@ def scrub_attribute(node, attr_node)
end

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

if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
Expand Down
50 changes: 50 additions & 0 deletions test/sanitizer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,56 @@ def test_disallow_the_dangerous_safelist_combination_of_select_and_style
refute_includes(sanitized, "style")
end

%w[text/plain text/css image/png image/gif image/jpeg].each do |mediatype|
define_method "test_mediatype_#{mediatype}_allowed" do
input = %Q(<img src="data:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = input
actual = safe_list_sanitize(input)
assert_equal(expected, actual)

input = %Q(<img src="DATA:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = input
actual = safe_list_sanitize(input)
assert_equal(expected, actual)
end
end

def test_mediatype_text_html_disallowed
input = %q(<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = %q(<img>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)

input = %q(<img src="DATA:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = %q(<img>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)
end

def test_mediatype_image_svg_xml_disallowed
input = %q(<img src="data:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = %q(<img>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)

input = %q(<img src="DATA:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
expected = %q(<img>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)
end

def test_mediatype_other_disallowed
input = %q(<a href="data:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
expected = %q(<a>foo</a>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)

input = %q(<a href="DATA:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>)
expected = %q(<a>foo</a>)
actual = safe_list_sanitize(input)
assert_equal(expected, actual)
end

def test_scrubbing_svg_attr_values_that_allow_ref
input = %Q(<div fill="yellow url(http://bad.com/) #fff">hey</div>)
expected = %Q(<div fill="yellow #fff">hey</div>)
Expand Down

0 comments on commit d1223a2

Please sign in to comment.