From 0713caf2ee23801cfb85e37065cf406368b20082 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 25 Aug 2022 15:03:39 -0400 Subject: [PATCH] fix: escape CDATA nodes using Loofah's escaping methods Also, notably, document the decisions behind this approach in a decision record. --- lib/rails/html/scrubbers.rb | 6 ++-- test/sanitizer_test.rb | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/lib/rails/html/scrubbers.rb b/lib/rails/html/scrubbers.rb index f9e14cd..674d1c4 100644 --- a/lib/rails/html/scrubbers.rb +++ b/lib/rails/html/scrubbers.rb @@ -61,9 +61,9 @@ def attributes=(attributes) end def scrub(node) - if node.cdata? - text = node.document.create_text_node node.text - node.replace text + if Loofah::HTML5::Scrub.cdata_needs_escaping?(node) + replacement = Loofah::HTML5::Scrub.cdata_escape(node) + node.replace(replacement) return CONTINUE end return CONTINUE if skip_node?(node) diff --git a/test/sanitizer_test.rb b/test/sanitizer_test.rb index 99221db..cd0b046 100644 --- a/test/sanitizer_test.rb +++ b/test/sanitizer_test.rb @@ -641,6 +641,66 @@ def test_scrubbing_svg_attr_values_that_allow_ref assert_equal(expected, actual) end + def test_style_with_css_payload + input, tags = "", ["style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + + def test_combination_of_select_and_style_with_css_payload + input, tags = "", ["select", "style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + + def test_combination_of_select_and_style_with_script_payload + input, tags = "", ["select", "style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + + def test_combination_of_svg_and_style_with_script_payload + input, tags = "", ["svg", "style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + + def test_combination_of_math_and_style_with_img_payload + input, tags = "", ["math", "style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + + input, tags = "", ["math", "style", "img"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + + def test_combination_of_svg_and_style_with_img_payload + input, tags = "", ["svg", "style"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + + input, tags = "", ["svg", "style", "img"] + expected = "" + actual = safe_list_sanitize(input, tags: tags) + + assert_equal(expected, actual) + end + protected def xpath_sanitize(input, options = {})