diff --git a/lib/rails/html/scrubbers.rb b/lib/rails/html/scrubbers.rb index 13b6d6f..315be4e 100644 --- a/lib/rails/html/scrubbers.rb +++ b/lib/rails/html/scrubbers.rb @@ -144,6 +144,13 @@ def scrub_attribute(node, attr_node) 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 + elsif val_unescaped.split(Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR)[0] == "data" + # permit only allowed data mediatypes + mediatype = val_unescaped.split(Loofah::HTML5::SafeList::PROTOCOL_SEPARATOR)[1] + mediatype, _ = mediatype.split(";")[0..1] if mediatype + if mediatype && !Loofah::HTML5::SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype) + attr_node.remove + end end end if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name) diff --git a/test/sanitizer_test.rb b/test/sanitizer_test.rb index df8e64b..9920023 100644 --- a/test/sanitizer_test.rb +++ b/test/sanitizer_test.rb @@ -515,6 +515,16 @@ def test_allow_data_attribute_if_requested assert_equal %(foo), safe_list_sanitize(text, attributes: ['data-foo']) end + def test_sanitize_data_protocol + text = "- XSS\">), safe_list_sanitize(text) + end + end + end + def test_uri_escaping_of_href_attr_in_a_tag_in_safe_list_sanitizer skip if RUBY_VERSION < "2.3"