Skip to content

Commit e323a77

Browse files
authored
Merge pull request #172 from flavorjones/171-xss-vulnerability
171 xss vulnerability
2 parents 1bdf276 + 1d81f91 commit e323a77

File tree

3 files changed

+51
-30
lines changed

3 files changed

+51
-30
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 2.3.1 / 2019-10-22
4+
5+
### Security
6+
7+
Address CVE-2019-15587: Unsanitized JavaScript may occur in sanitized output when a crafted SVG element is republished.
8+
9+
This CVE's public notice is at https://github.com/flavorjones/loofah/issues/171
10+
11+
312
## 2.3.0 / 2019-09-28
413

514
### Features

lib/loofah/html5/safelist.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require 'set'
1+
require "set"
22

33
module Loofah
44
module HTML5 # :nodoc:
@@ -45,7 +45,6 @@ module HTML5 # :nodoc:
4545
#
4646
# </html5_license>
4747
module SafeList
48-
4948
ACCEPTABLE_ELEMENTS = Set.new([
5049
"a",
5150
"abbr",
@@ -361,7 +360,6 @@ module SafeList
361360
"baseProfile",
362361
"bbox",
363362
"begin",
364-
"by",
365363
"calcMode",
366364
"cap-height",
367365
"class",
@@ -468,7 +466,6 @@ module SafeList
468466
"systemLanguage",
469467
"target",
470468
"text-anchor",
471-
"to",
472469
"transform",
473470
"type",
474471
"u1",
@@ -478,7 +475,6 @@ module SafeList
478475
"unicode",
479476
"unicode-range",
480477
"units-per-em",
481-
"values",
482478
"version",
483479
"viewBox",
484480
"visibility",

test/integration/test_ad_hoc.rb

+41-25
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
require "helper"
22

33
class IntegrationTestAdHoc < Loofah::TestCase
4-
54
context "blank input string" do
65
context "fragment" do
76
it "return a blank string" do
@@ -33,9 +32,9 @@ def test_removal_of_illegal_attribute
3332
html = "<p class=bar foo=bar abbr=bar />"
3433
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml)
3534
node = sane.xpath("//p").first
36-
assert node.attributes['class']
37-
assert node.attributes['abbr']
38-
assert_nil node.attributes['foo']
35+
assert node.attributes["class"]
36+
assert node.attributes["abbr"]
37+
assert_nil node.attributes["foo"]
3938
end
4039

4140
def test_removal_of_illegal_url_in_href
@@ -45,14 +44,14 @@ def test_removal_of_illegal_url_in_href
4544
HTML
4645
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml)
4746
nodes = sane.xpath("//a")
48-
assert_nil nodes.first.attributes['href']
49-
assert nodes.last.attributes['href']
47+
assert_nil nodes.first.attributes["href"]
48+
assert nodes.last.attributes["href"]
5049
end
5150

5251
def test_css_sanitization
5352
html = "<p style='background-color: url(\"http://foo.com/\") ; background-color: #000 ;' />"
5453
sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml)
55-
assert_match %r/#000/, sane.inner_html
54+
assert_match %r/#000/, sane.inner_html
5655
refute_match %r/foo\.com/, sane.inner_html
5756
end
5857

@@ -75,7 +74,7 @@ def test_fragment_with_text_nodes_leading_and_trailing
7574
def test_whitewash_on_fragment
7675
html = "safe<frameset rows=\"*\"><frame src=\"http://example.com\"></frameset> <b>description</b>"
7776
whitewashed = Loofah.scrub_document(html, :whitewash).xpath("/html/body/*").to_s
78-
assert_equal "<p>safe</p><b>description</b>", whitewashed.gsub("\n","")
77+
assert_equal "<p>safe</p><b>description</b>", whitewashed.gsub("\n", "")
7978
end
8079

8180
def test_fragment_whitewash_on_microsofty_markup
@@ -86,11 +85,11 @@ def test_fragment_whitewash_on_microsofty_markup
8685
def test_document_whitewash_on_microsofty_markup
8786
whitewashed = Loofah.document(MSWORD_HTML).scrub!(:whitewash)
8887
assert_match %r(<p>Foo <b>BOLD</b></p>), whitewashed.to_s
89-
assert_equal "<p>Foo <b>BOLD</b></p>", whitewashed.xpath("/html/body/*").to_s
88+
assert_equal "<p>Foo <b>BOLD</b></p>", whitewashed.xpath("/html/body/*").to_s
9089
end
9190

9291
def test_return_empty_string_when_nothing_left
93-
assert_equal "", Loofah.scrub_document('<script>test</script>', :prune).text
92+
assert_equal "", Loofah.scrub_document("<script>test</script>", :prune).text
9493
end
9594

9695
def test_nested_script_cdata_tags_should_be_scrubbed
@@ -145,21 +144,20 @@ def test_dont_remove_whitespace_between_tags
145144
#
146145
# https://git.gnome.org/browse/libxml2/tree/HTMLtree.c?h=v2.9.2#n714
147146
#
148-
{tag: "a", attr: "href"},
149-
{tag: "div", attr: "href"},
150-
{tag: "a", attr: "action"},
151-
{tag: "div", attr: "action"},
152-
{tag: "a", attr: "src"},
153-
{tag: "div", attr: "src"},
154-
{tag: "a", attr: "name"},
147+
{ tag: "a", attr: "href" },
148+
{ tag: "div", attr: "href" },
149+
{ tag: "a", attr: "action" },
150+
{ tag: "div", attr: "action" },
151+
{ tag: "a", attr: "src" },
152+
{ tag: "div", attr: "src" },
153+
{ tag: "a", attr: "name" },
155154
#
156155
# note that div+name is _not_ affected by the libxml2 issue.
157156
# but we test it anyway to ensure our logic isn't modifying
158157
# attributes that don't need modifying.
159158
#
160-
{tag: "div", attr: "name", unescaped: true},
159+
{ tag: "div", attr: "name", unescaped: true },
161160
].each do |config|
162-
163161
define_method "test_uri_escaping_of_#{config[:attr]}_attr_in_#{config[:tag]}_tag" do
164162
html = %{<#{config[:tag]} #{config[:attr]}='examp<!--" unsafeattr=foo()>-->le.com'>test</#{config[:tag]}>}
165163

@@ -190,14 +188,32 @@ def test_dont_remove_whitespace_between_tags
190188
end
191189
end
192190

193-
# see:
194-
# - https://github.com/flavorjones/loofah/issues/154
195-
# - https://hackerone.com/reports/429267
196-
context "xss protection from svg xmlns:xlink animate attribute" do
197-
it "sanitizes appropriate attributes" do
198-
html = %Q{<svg><a xmlns:xlink=http://www.w3.org/1999/xlink xlink:href=?><circle r=400 /><animate attributeName=xlink:href begin=0 from=javascript:alert(1) to=%26>}
191+
context "xss protection from svg animate attributes" do
192+
# see recommendation from https://html5sec.org/#137
193+
# to sanitize "to", "from", "values", and "by" attributes
194+
195+
it "sanitizes 'from', 'to', and 'by' attributes" do
196+
# for CVE-2018-16468
197+
# see:
198+
# - https://github.com/flavorjones/loofah/issues/154
199+
# - https://hackerone.com/reports/429267
200+
html = %Q{<svg><a xmlns:xlink=http://www.w3.org/1999/xlink xlink:href=?><circle r=400 /><animate attributeName=xlink:href begin=0 from=javascript:alert(1) to=%26 by=5>}
201+
199202
sanitized = Loofah.scrub_fragment(html, :escape)
200203
assert_nil sanitized.at_css("animate")["from"]
204+
assert_nil sanitized.at_css("animate")["to"]
205+
assert_nil sanitized.at_css("animate")["by"]
206+
end
207+
208+
it "sanitizes 'values' attribute" do
209+
# for CVE-2019-15587
210+
# see:
211+
# - https://github.com/flavorjones/loofah/issues/171
212+
# - https://hackerone.com/reports/709009
213+
html = %Q{<svg> <animate href="#foo" attributeName="href" values="javascript:alert('xss')"/> <a id="foo"> <circle r=400 /> </a> </svg>}
214+
215+
sanitized = Loofah.scrub_fragment(html, :escape)
216+
assert_nil sanitized.at_css("animate")["values"]
201217
end
202218
end
203219
end

0 commit comments

Comments
 (0)