In some circumstances, the new Sanitizer was double-escaping text nodes.
Fixed (with unit test).
This commit is contained in:
Jacques Distler 2008-05-21 14:14:43 -05:00
parent 45405fc97e
commit f6508de6dd
4 changed files with 20 additions and 9 deletions

View file

@ -149,7 +149,7 @@ module Sanitizer
end end
node.attributes.each do |attr,val| node.attributes.each do |attr,val|
if String === val if String === val
node.attributes[attr] = CGI.escapeHTML(CGI.unescapeHTML(val)) node.attributes[attr] = val.unescapeHTML.escapeHTML
else else
node.attributes.delete attr node.attributes.delete attr
end end

View file

@ -2214,7 +2214,9 @@ class String
def escapeHTML def escapeHTML
self.gsub( /&/, "&" ). self.gsub( /&/, "&" ).
gsub( /</, "&lt;" ). gsub( /</, "&lt;" ).
gsub( />/, "&gt;" ) gsub( />/, "&gt;" ).
gsub(/'/, "&apos;" ).
gsub(/"/, "&quot;" )
end end
def unescapeHTML def unescapeHTML
@ -2224,6 +2226,8 @@ class String
when /\Aamp\z/ni then '&' when /\Aamp\z/ni then '&'
when /\Agt\z/ni then '>' when /\Agt\z/ni then '>'
when /\Alt\z/ni then '<' when /\Alt\z/ni then '<'
when /\Aquot\z/ni then '"'
when /\Aapos\z/ni then "'"
when /\A#0*(\d+)\z/n then when /\A#0*(\d+)\z/n then
if Integer($1) < 256 if Integer($1) < 256
Integer($1).chr Integer($1).chr

View file

@ -3,14 +3,14 @@
"name": "IE_Comments", "name": "IE_Comments",
"input": "<!--[if gte IE 4]><script>alert('XSS');</script><![endif]-->", "input": "<!--[if gte IE 4]><script>alert('XSS');</script><![endif]-->",
"output": "", "output": "",
"xhtml": "&lt;!--[if gte IE 4]&gt;&lt;script&gt;alert('XSS');&lt;/script&gt;&lt;![endif]--&gt;" "xhtml": "&lt;!--[if gte IE 4]&gt;&lt;script&gt;alert(&apos;XSS&apos;);&lt;/script&gt;&lt;![endif]--&gt;"
}, },
{ {
"name": "IE_Comments_2", "name": "IE_Comments_2",
"input": "<![if !IE 5]><script>alert('XSS');</script><![endif]>", "input": "<![if !IE 5]><script>alert('XSS');</script><![endif]>",
"output": "&lt;script&gt;alert('XSS');&lt;/script&gt;", "output": "&lt;script&gt;alert('XSS');&lt;/script&gt;",
"xhtml": "&lt;![if !IE 5]&gt;&lt;script&gt;alert('XSS');&lt;/script&gt;&lt;![endif]&gt;", "xhtml": "&lt;![if !IE 5]&gt;&lt;script&gt;alert(&apos;XSS&apos;);&lt;/script&gt;&lt;![endif]&gt;",
"rexml": "Ill-formed XHTML!" "rexml": "Ill-formed XHTML!"
}, },
@ -359,7 +359,7 @@
"name": "should_sanitize_script_tag_with_multiple_open_brackets", "name": "should_sanitize_script_tag_with_multiple_open_brackets",
"input": "<<script>alert(\"XSS\");//<</script>", "input": "<<script>alert(\"XSS\");//<</script>",
"output": "&lt;&lt;script&gt;alert(\"XSS\");//&lt;&lt;/script&gt;", "output": "&lt;&lt;script&gt;alert(\"XSS\");//&lt;&lt;/script&gt;",
"xhtml": "&lt;&lt;script&gt;alert(\"XSS\");//&lt;&lt;/script&gt;", "xhtml": "&lt;&lt;script&gt;alert(&quot;XSS&quot;);//&lt;&lt;/script&gt;",
"rexml": "Ill-formed XHTML!" "rexml": "Ill-formed XHTML!"
}, },
@ -375,7 +375,7 @@
"name": "should_sanitize_tag_broken_up_by_null", "name": "should_sanitize_tag_broken_up_by_null",
"input": "<scr\u0000ipt>alert(\"XSS\")</scr\u0000ipt>", "input": "<scr\u0000ipt>alert(\"XSS\")</scr\u0000ipt>",
"output": "&lt;scr\ufffdipt&gt;alert(\"XSS\")&lt;/scr\ufffdipt&gt;", "output": "&lt;scr\ufffdipt&gt;alert(\"XSS\")&lt;/scr\ufffdipt&gt;",
"xhtml": "&lt;scr&gt;alert(\"XSS\")&lt;/scr&gt;", "xhtml": "&lt;scr&gt;alert(&quot;XSS&quot;)&lt;/scr&gt;",
"rexml": "Ill-formed XHTML!" "rexml": "Ill-formed XHTML!"
}, },

View file

@ -102,6 +102,13 @@ class PageRendererTest < Test::Unit::TestCase
%{return ThatWay</code></pre>\n\n<p>Nice!</p>}, %{return ThatWay</code></pre>\n\n<p>Nice!</p>},
code_block) code_block)
assert_markup_parsed_as(%{<p>You then needed to edit (or create) a user.js file in} +
%{ your Mozilla profile, which read either (<span class='newWikiWord'>Mac OSX<a h} +
%{ref='../show/MacOSX'>?</a></span>)</p>\n\n<pre><code> user_pref(&quot;font.mat} +
%{hfont-family&quot;, &quot;Math1,Math2,Math4,Symbol&quot;);</code></pre>},
%{You then needed to edit (or create) a user.js file in your Mozilla profile, whic} +
%{h read either (MacOSX)\n\n user_pref("font.mathfont-family", "Math1,Math2,Math4,Symbol");})
assert_markup_parsed_as( assert_markup_parsed_as(
%{<p><math class='maruku-mathml' } + %{<p><math class='maruku-mathml' } +
%{display='inline' xmlns='http://www.w3.org/1998/Math/MathML'>} + %{display='inline' xmlns='http://www.w3.org/1998/Math/MathML'>} +
@ -299,7 +306,7 @@ class PageRendererTest < Test::Unit::TestCase
def test_sanitize_nowiki_tag def test_sanitize_nowiki_tag
assert_markup_parsed_as( assert_markup_parsed_as(
'<p>[[test]]&amp;<a href=\'a&amp;b\'>shebang</a> &lt;script&gt;alert("xss!");&lt;/script&gt; *foo*</p>', '<p>[[test]]&amp;<a href=\'a&amp;b\'>shebang</a> &lt;script&gt;alert(&quot;xss!&quot;);&lt;/script&gt; *foo*</p>',
'<nowiki>[[test]]&<a href="a&b">shebang</a> <script>alert("xss!");</script> *foo*</nowiki>') '<nowiki>[[test]]&<a href="a&b">shebang</a> <script>alert("xss!");</script> *foo*</nowiki>')
end end
@ -349,7 +356,7 @@ class PageRendererTest < Test::Unit::TestCase
def test_difficult_wiki_words def test_difficult_wiki_words
@revision.content = "[[It's just awesome GUI!]]" @revision.content = "[[It's just awesome GUI!]]"
assert_equal "<p><span class='newWikiWord'>It's just awesome GUI!" + assert_equal "<p><span class='newWikiWord'>It&apos;s just awesome GUI!" +
"<a href='../show/It%27s+just+awesome+GUI%21'>?</a></span></p>", "<a href='../show/It%27s+just+awesome+GUI%21'>?</a></span></p>",
test_renderer(@revision).display_content test_renderer(@revision).display_content
end end
@ -366,7 +373,7 @@ class PageRendererTest < Test::Unit::TestCase
def test_nowiki_sanitization def test_nowiki_sanitization
assert_markup_parsed_as('<p>This sentence contains <span>a &amp; b</span> ' + assert_markup_parsed_as('<p>This sentence contains <span>a &amp; b</span> ' +
'&lt;script&gt;alert("XSS!");&lt;/script&gt;. Do not touch!</p>', '&lt;script&gt;alert(&quot;XSS!&quot;);&lt;/script&gt;. Do not touch!</p>',
'This sentence contains <nowiki><span>a & b</span> <script>alert("XSS!");' + 'This sentence contains <nowiki><span>a & b</span> <script>alert("XSS!");' +
'</script></nowiki>. Do not touch!') '</script></nowiki>. Do not touch!')
end end