Skip to content

Commit

Permalink
fix: escape CDATA nodes using Loofah's escaping methods
Browse files Browse the repository at this point in the history
Also, notably, document the decisions behind this approach in a
decision record.
  • Loading branch information
flavorjones committed Dec 11, 2022
1 parent e6d52d3 commit 0713caf
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/rails/html/scrubbers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
60 changes: 60 additions & 0 deletions test/sanitizer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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>div > span { background: \"red\"; }</style>", ["style"]
expected = "<style>div &gt; span { background: \"red\"; }</style>"
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>div > span { background: \"red\"; }</style></select>", ["select", "style"]
expected = "<select><style>div &gt; span { background: \"red\"; }</style></select>"
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><script>alert(1)</script></style></select>", ["select", "style"]
expected = "<select><style>&lt;script&gt;alert(1)&lt;/script&gt;</style></select>"
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><script>alert(1)</script></style></svg>", ["svg", "style"]
expected = "<svg><style>&lt;script&gt;alert(1)&lt;/script&gt;</style></svg>"
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><img src=x onerror=alert(1)></style></math>", ["math", "style"]
expected = "<math><style>&lt;img src=x onerror=alert(1)&gt;</style></math>"
actual = safe_list_sanitize(input, tags: tags)

assert_equal(expected, actual)

input, tags = "<math><style><img src=x onerror=alert(1)></style></math>", ["math", "style", "img"]
expected = "<math><style>&lt;img src=x onerror=alert(1)&gt;</style></math>"
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><img src=x onerror=alert(1)></style></svg>", ["svg", "style"]
expected = "<svg><style>&lt;img src=x onerror=alert(1)&gt;</style></svg>"
actual = safe_list_sanitize(input, tags: tags)

assert_equal(expected, actual)

input, tags = "<svg><style><img src=x onerror=alert(1)></style></svg>", ["svg", "style", "img"]
expected = "<svg><style>&lt;img src=x onerror=alert(1)&gt;</style></svg>"
actual = safe_list_sanitize(input, tags: tags)

assert_equal(expected, actual)
end

protected

def xpath_sanitize(input, options = {})
Expand Down

0 comments on commit 0713caf

Please # to comment.