• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.mail.utils;
2 
3 import android.test.AndroidTestCase;
4 import android.test.suitebuilder.annotation.SmallTest;
5 
6 /**
7  * These test cases verify that each white listed element and attribute is accepted by the sanitizer
8  * and everything else is correctly discarded.
9  */
10 @SmallTest
11 public class BasicHtmlSanitizerTest extends AndroidTestCase {
testAttributeDir()12     public void testAttributeDir() {
13         sanitize("<div dir=\"ltr\">something</div>", "<div dir=\"ltr\">something</div>");
14         sanitize("<div dir=\"rtl\">something</div>", "<div dir=\"rtl\">something</div>");
15         sanitize("<div dir=\"LTR\">something</div>", "<div dir=\"ltr\">something</div>");
16         sanitize("<div dir=\"RTL\">something</div>", "<div dir=\"rtl\">something</div>");
17         sanitize("<div dir=\"blah\">something</div>", "<div>something</div>");
18     }
19 
testA()20     public void testA() {
21         // allowed attributes
22         sanitize("<a coords=\"something\"></a>", "<a coords=\"something\"></a>");
23         sanitize("<a href=\"http://www.here.com\"></a>", "<a href=\"http://www.here.com\"></a>");
24         sanitize("<a name=\"something\"></a>", "<a name=\"something\"></a>");
25         sanitize("<a shape=\"something\"></a>", "<a shape=\"something\"></a>");
26 
27         // disallowed attributes (all links should launch a browser so we don't need these)
28         sanitize("<a charset=\"something\"></a>", "");
29         sanitize("<a datafld=\"something\"></a>", "");
30         sanitize("<a datasrc=\"something\"></a>", "");
31         sanitize("<a download=\"something\"></a>", "");
32         sanitize("<a href=\"javascript:badness()\"></a>", "");
33         sanitize("<a hreflang=\"something\"></a>", "");
34         sanitize("<a media=\"something\"></a>", "");
35         sanitize("<a methods=\"something\"></a>", "");
36         sanitize("<a ping=\"something\"></a>", "");
37         sanitize("<a rel=\"something\"></a>", "");
38         sanitize("<a rev=\"something\"></a>", "");
39         sanitize("<a target=\"_top\"></a>", "");
40         sanitize("<a type=\"_top\"></a>", "");
41         sanitize("<a urn=\"_top\"></a>", "");
42         sanitize("<a onmouseout=\"alert(document.cookie)\">xxs link</a>", "xxs link");
43         sanitize("<a onmouseover=\"alert(document.cookie)\">xxs link</a>", "xxs link");
44         sanitize("<a onmouseover=alert(document.cookie)>xxs link</a>", "xxs link");
45         sanitize("exp/*<a style='no\\xss:noxss(\"*//*\");\n" +
46                 "xss:ex/*XSS*//*/*/pression(alert(\"XSS\"))'>", "exp/*");
47     }
48 
testAbbr()49     public void testAbbr() {
50         sanitize("<abbr title=\"United Kingdom\">UK</abbr>",
51                 "<abbr title=\"United Kingdom\">UK</abbr>");
52     }
53 
testAcronym()54     public void testAcronym() {
55         sanitize("<acronym title=\"World Wide Web\">WWW</acronym>",
56                 "<acronym title=\"World Wide Web\">WWW</acronym>");
57     }
58 
testAddress()59     public void testAddress() {
60         sanitize("<address>something</address>", "<address>something</address>");
61     }
62 
testApplet()63     public void testApplet() {
64         // todo Gmail would also strip "malicious applet" as well... is this a problem?
65         sanitize("<applet>malicious applet</applet>", "malicious applet");
66     }
67 
testArea()68     public void testArea() {
69         // allowed attributes
70         sanitize("<area alt=\"something\"/>", "<area alt=\"something\" />");
71         sanitize("<area coords=\"something\"/>", "<area coords=\"something\" />");
72         sanitize("<area href=\"http://www.here.com\"/>", "<area href=\"http://www.here.com\" />");
73         sanitize("<area name=\"something\"/>", "<area name=\"something\" />");
74         sanitize("<area nohref />", "<area nohref=\"nohref\" />");
75         sanitize("<area shape=\"something\"/>", "<area shape=\"something\" />");
76 
77         // disallowed attributes (all links launch a browser so we don't need these attributes)
78         sanitize("<area accessKey=\"A\"/>", "<area />");
79         sanitize("<area download=\"something\"/>", "<area />");
80         sanitize("<area href=\"javascript:badness()\"/>", "<area />");
81         sanitize("<area hreflang=\"something\"/>", "<area />");
82         sanitize("<area media=\"something\"/>", "<area />");
83         sanitize("<area rel=\"something\"/>", "<area />");
84         sanitize("<area target=\"something\"/>", "<area />");
85         sanitize("<area tabindex=\"something\"/>", "<area />");
86         sanitize("<area type=\"something\"/>", "<area />");
87     }
88 
testArticle()89     public void testArticle() {
90         sanitize("<article></article>", "<article></article>");
91     }
92 
testAside()93     public void testAside() {
94         sanitize("<aside></aside>", "<aside></aside>");
95     }
96 
testAudio()97     public void testAudio() {
98         sanitize("<audio>not supported</audio>", "not supported");
99     }
100 
testB()101     public void testB() {
102         sanitize("<b>something</b>", "<b>something</b>");
103     }
104 
testBase()105     public void testBase() {
106         // allowed attributes
107         sanitize("<base href=\"http://www.example.com/\">",
108                 "<base href=\"http://www.example.com/\" />");
109 
110         // disallowed attributes
111         sanitize("<base target=\"_blank\">", "<base />");
112         sanitize("<base href=\"javascript:badness()\">", "<base />");
113         sanitize("<base href=\"javascript:alert('XSS');//\">", "<base />");
114     }
115 
testBasefont()116     public void testBasefont() {
117         sanitize("<basefont color=\"something\"/>", "");
118         sanitize("<basefont face=\"something\"/>", "");
119         sanitize("<basefont size=\"something\"/>", "");
120     }
121 
testBdi()122     public void testBdi() {
123         sanitize("<bdi>something</bdi>", "<bdi>something</bdi>");
124         sanitize("<bdi dir=\"ltr\">something</bdi>", "<bdi dir=\"ltr\">something</bdi>");
125     }
126 
testBdo()127     public void testBdo() {
128         sanitize("<bdo>something</bdo>", "<bdo>something</bdo>");
129         sanitize("<bdo dir=\"ltr\">something</bdo>", "<bdo dir=\"ltr\">something</bdo>");
130     }
131 
testBgsound()132     public void testBgsound() {
133         sanitize("<bgsound src=\"sound1.mid\">", "");
134         sanitize("<bgsound src=\"javascript:alert('XSS');\">", "");
135     }
136 
testBig()137     public void testBig() {
138         sanitize("<big>something</big>", "<big>something</big>");
139     }
140 
testBlink()141     public void testBlink() {
142         sanitize("<blink>something</blink>", "something");
143     }
144 
testBlockquote()145     public void testBlockquote() {
146         sanitize("<blockquote>something</blockquote>", "<blockquote>something</blockquote>");
147         sanitize("<blockquote cite=\"http://www.here.com\">something</blockquote>",
148                 "<blockquote cite=\"http://www.here.com\">something</blockquote>");
149         sanitize("<blockquote cite=\"javascript:badness()\">something</blockquote>",
150                 "<blockquote>something</blockquote>");
151 
152         sanitize("<blockquote style=\"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;" +
153                 "padding-left:1ex\">",
154                 "<blockquote style=\"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;" +
155                         "padding-left:1ex\"></blockquote>");
156     }
157 
158     /**
159      * The body tag will be supplied by code that wraps this email with other formatting logic.
160      * So, any body tags appearing within the email are translated to div tags.
161      */
testBody()162     public void testBody() {
163         sanitize("<body alink=\"something\"></body>", "<div></div>");
164         sanitize("<body background=\"something\"></body>", "<div></div>");
165         sanitize("<body bgcolor=\"something\"></body>", "<div></div>");
166         sanitize("<body link=\"something\"></body>", "<div></div>");
167         sanitize("<body text=\"something\"></body>", "<div></div>");
168         sanitize("<body vlink=\"something\"></body>", "<div></div>");
169 
170         // take extra care to ensure that these scripting callbacks don't survive
171         sanitize("<body onafterprint=\"something\"></body>", "<div></div>");
172         sanitize("<body onbeforeprint=\"something\"></body>", "<div></div>");
173         sanitize("<body onbeforeunload=\"something\"></body>", "<div></div>");
174         sanitize("<body onblur=\"something\"></body>", "<div></div>");
175         sanitize("<body onerror=\"something\"></body>", "<div></div>");
176         sanitize("<body onfocus=\"something\"></body>", "<div></div>");
177         sanitize("<body onhashchange=\"something\"></body>", "<div></div>");
178         sanitize("<body onload=\"something\"></body>", "<div></div>");
179         sanitize("<body onmessage=\"something\"></body>", "<div></div>");
180         sanitize("<body onoffline=\"something\"></body>", "<div></div>");
181         sanitize("<body ononline=\"something\"></body>", "<div></div>");
182         sanitize("<body onpopstate=\"something\"></body>", "<div></div>");
183         sanitize("<body onredo=\"something\"></body>", "<div></div>");
184         sanitize("<body onresize=\"something\"></body>", "<div></div>");
185         sanitize("<body onstorage=\"something\"></body>", "<div></div>");
186         sanitize("<body onundo=\"something\"></body>", "<div></div>");
187         sanitize("<body onunload=\"something\"></body>", "<div></div>");
188         sanitize("<body onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<div></div>");
189         sanitize("<body background=\"javascript:alert('XSS')\">", "<div></div>");
190         sanitize("<body onload=alert('XSS')>", "<div></div>");
191         sanitize("<body onload =alert('XSS')>", "<div></div>");
192     }
193 
testBr()194     public void testBr() {
195         sanitize("something<br>something", "something<br />something");
196         sanitize("something<br clear=\"all\">something", "something<br clear=\"all\" />something");
197     }
198 
testButton()199     public void testButton() {
200         sanitize("<button>Click Me!</button>", "<button>Click Me!</button>");
201         sanitize("<button autofocus=\"true\">Click Me!</button>",
202                 "<button autofocus=\"true\">Click Me!</button>");
203         sanitize("<button disabled=\"true\">Click Me!</button>",
204                 "<button disabled=\"true\">Click Me!</button>");
205         sanitize("<button formenctype=\"text/plain\">Click Me!</button>",
206                 "<button formenctype=\"text/plain\">Click Me!</button>");
207         sanitize("<button formmethod=\"post\">Click Me!</button>",
208                 "<button formmethod=\"post\">Click Me!</button>");
209         sanitize("<button formnovalidate=\"formnovalidate\">Click Me!</button>",
210                 "<button formnovalidate=\"formnovalidate\">Click Me!</button>");
211         sanitize("<button formtarget=\"_top\">Click Me!</button>",
212                 "<button formtarget=\"_top\">Click Me!</button>");
213         sanitize("<button name=\"something\">Click Me!</button>",
214                 "<button name=\"something\">Click Me!</button>");
215         sanitize("<button type=\"button\">Click Me!</button>",
216                 "<button type=\"button\">Click Me!</button>");
217         sanitize("<button value=\"something\">Click Me!</button>",
218                 "<button value=\"something\">Click Me!</button>");
219         sanitize("<button formaction=\"http://www.overhere.com/\">Click Me!</button>",
220                 "<button formaction=\"http://www.overhere.com/\">Click Me!</button>");
221 
222         sanitize("<button formaction=\"javascript:badness()\">Click Me!</button>",
223                 "<button>Click Me!</button>");
224     }
225 
testCanvas()226     public void testCanvas() {
227         sanitize("<canvas></canvas>", "<canvas></canvas>");
228         sanitize("<canvas width=\"500\"></canvas>", "<canvas width=\"500\"></canvas>");
229         sanitize("<canvas height=\"500\"></canvas>", "<canvas height=\"500\"></canvas>");
230     }
231 
testCaption()232     public void testCaption() {
233         sanitize("<caption>something</caption>", "<caption>something</caption>");
234         sanitize("<caption align=\"left\">something</caption>",
235                 "<caption align=\"left\">something</caption>");
236     }
237 
testCenter()238     public void testCenter() {
239         sanitize("<center>something</center>", "<center>something</center>");
240     }
241 
testCite()242     public void testCite() {
243         sanitize("<cite>something</cite>", "<cite>something</cite>");
244     }
245 
testCode()246     public void testCode() {
247         sanitize("<code>something</code>", "<code>something</code>");
248     }
249 
testCol()250     public void testCol() {
251         sanitize("<col>", "<col />");
252         sanitize("<col align=\"left\">", "<col align=\"left\" />");
253         sanitize("<col bgcolor=\"something\">", "<col bgcolor=\"something\" />");
254         sanitize("<col char=\"something\">", "<col char=\"something\" />");
255         sanitize("<col charoff=\"something\">", "<col charoff=\"something\" />");
256         sanitize("<col span=\"something\">", "<col span=\"something\" />");
257         sanitize("<col valign=\"something\">", "<col valign=\"something\" />");
258         sanitize("<col width=\"something\">", "<col width=\"something\" />");
259     }
260 
testColgroup()261     public void testColgroup() {
262         sanitize("<colgroup></colgroup>", "<colgroup></colgroup>");
263         sanitize("<colgroup align=\"left\"></colgroup>", "<colgroup align=\"left\"></colgroup>");
264         sanitize("<colgroup char=\"something\"></colgroup>",
265                 "<colgroup char=\"something\"></colgroup>");
266         sanitize("<colgroup charoff=\"something\"></colgroup>",
267                 "<colgroup charoff=\"something\"></colgroup>");
268         sanitize("<colgroup span=\"something\"></colgroup>",
269                 "<colgroup span=\"something\"></colgroup>");
270         sanitize("<colgroup valign=\"something\"></colgroup>",
271                 "<colgroup valign=\"something\"></colgroup>");
272         sanitize("<colgroup width=\"something\"></colgroup>",
273                 "<colgroup width=\"something\"></colgroup>");
274     }
275 
testDatalist()276     public void testDatalist() {
277         sanitize("<datalist></datalist>", "<datalist></datalist>");
278     }
279 
testDd()280     public void testDd() {
281         sanitize("<dd>something</dd>", "<dd>something</dd>");
282     }
283 
testDel()284     public void testDel() {
285         sanitize("<del>something</del>", "<del>something</del>");
286         sanitize("<del cite=\"javascript:badness();\">something</del>", "<del>something</del>");
287         sanitize("<del cite=\"http://www.reason.com/\">something</del>",
288                 "<del cite=\"http://www.reason.com/\">something</del>");
289         sanitize("<del datetime=\"something\">something</del>",
290                 "<del datetime=\"something\">something</del>");
291     }
292 
testDetails()293     public void testDetails() {
294         sanitize("<details>something</details>", "<details>something</details>");
295     }
296 
testDfn()297     public void testDfn() {
298         sanitize("<dfn>something</dfn>", "<dfn>something</dfn>");
299     }
300 
testDialog()301     public void testDialog() {
302         sanitize("<dialog open>This is an open dialog window</dialog>",
303                 "This is an open dialog window");
304     }
305 
testDir()306     public void testDir() {
307         sanitize("<dir><li>something</li></dir>", "<dir><li>something</li></dir>");
308         sanitize("<dir compact=\"compact\"><li>something</li></dir>",
309                 "<dir compact=\"compact\"><li>something</li></dir>");
310     }
311 
testDiv()312     public void testDiv() {
313         sanitize("<div></div>", "<div></div>");
314         sanitize("<div align=\"left\"></div>", "<div align=\"left\"></div>");
315         sanitize("<div background=\"http://www.random.com/mypng.gif\"></div>",
316                 "<div background=\"http://www.random.com/mypng.gif\"></div>");
317 
318         sanitize("<div background=\"javascript:badness();\"></div>", "<div></div>");
319         sanitize("<div style=\"width: expression(alert('XSS'));\">", "<div></div>");
320         sanitize("<div style=\"background-image: url(javascript:alert('XSS'))\">", "<div></div>");
321         sanitize("<div style=\"background-image:\\0075\\0072\\006C\\0028'\\006a\\0061\\0076\\0061" +
322                 "\\0073\\0063\\0072\\0069\\0070\\0074\\003a\\0061\\006c\\0065\\0072\\0074" +
323                 "\\0028.1027\\0058.1053\\0053\\0027\\0029'\\0029\">", "<div></div>");
324         sanitize("<div style=\"background-image: url(&#1;javascript:alert('XSS'))\">",
325                 "<div></div>");
326     }
327 
testDl()328     public void testDl() {
329         sanitize("<dl></dl>", "<dl></dl>");
330     }
331 
testDt()332     public void testDt() {
333         sanitize("<dt></dt>", "<dt></dt>");
334     }
335 
testEm()336     public void testEm() {
337         sanitize("<em>something</em>", "<em>something</em>");
338     }
339 
testEmbed()340     public void testEmbed() {
341         sanitize("<embed src=\"helloworld.swf\">", "");
342     }
343 
testFieldset()344     public void testFieldset() {
345         sanitize("<fieldset>something</fieldset>", "<fieldset>something</fieldset>");
346         sanitize("<fieldset disabled=\"true\">something</fieldset>",
347                 "<fieldset disabled=\"true\">something</fieldset>");
348         sanitize("<fieldset form=\"formId\">something</fieldset>",
349                 "<fieldset form=\"formId\">something</fieldset>");
350         sanitize("<fieldset name=\"something\">something</fieldset>",
351                 "<fieldset name=\"something\">something</fieldset>");
352     }
353 
testFigcaption()354     public void testFigcaption() {
355         sanitize("<figcaption>Fig1. something</figcaption>",
356                 "<figcaption>Fig1. something</figcaption>");
357     }
358 
testFigure()359     public void testFigure() {
360         sanitize("<figure>something</figure>", "<figure>something</figure>");
361     }
362 
testFont()363     public void testFont() {
364         sanitize("<font>something</font>", "something");
365         sanitize("<font size=\"3\">something</font>", "<font size=\"3\">something</font>");
366         sanitize("<font face=\"verdana\">something</font>",
367                 "<font face=\"verdana\">something</font>");
368         sanitize("<font color=\"red\">something</font>", "<font color=\"red\">something</font>");
369     }
370 
testFooter()371     public void testFooter() {
372         sanitize("<footer>something</footer>", "<footer>something</footer>");
373     }
374 
testForm()375     public void testForm() {
376         sanitize("<form></form>", "<form></form>");
377         sanitize("<form accept=\"something\"></form>", "<form accept=\"something\"></form>");
378         sanitize("<form accept-charset=\"something\"></form>",
379                 "<form accept-charset=\"something\"></form>");
380         sanitize("<form autocomplete=\"on\"></form>", "<form autocomplete=\"on\"></form>");
381         sanitize("<form enctype=\"text/plain\"></form>", "<form enctype=\"text/plain\"></form>");
382         sanitize("<form method=\"get\"></form>", "<form method=\"get\"></form>");
383         sanitize("<form name=\"something\"></form>", "<form name=\"something\"></form>");
384         sanitize("<form novalidate=\"novalidate\"></form>",
385                 "<form novalidate=\"novalidate\"></form>");
386         sanitize("<form target=\"_top\"></form>", "<form target=\"_top\"></form>");
387         sanitize("<form action=\"http://www.overhere.com/\"></form>",
388                 "<form action=\"http://www.overhere.com/\"></form>");
389 
390         sanitize("<form action=\"javascript:badness()\"></form>", "<form></form>");
391         sanitize("<form onsubmit=\"javascript:badness()\"></form>", "<form></form>");
392         sanitize("<form onreset=\"javascript:badness()\"></form>", "<form></form>");
393     }
394 
testFrame()395     public void testFrame() {
396         sanitize("<frame src=\"frame_a.htm\">", "");
397     }
398 
testFrameset()399     public void testFrameset() {
400         sanitize("<frameset cols=\"25%,*,25%\"></frameset>", "");
401         sanitize("<frameset><frame src=\"javascript:alert('XSS');\"></frameset>", "");
402     }
403 
testHead()404     public void testHead() {
405         sanitize("<head></head>", "");
406         sanitize("<head profile=\"http://www.overhere.com/\"></head>", "");
407         sanitize("<head profile=\"javascript:badness()\"></head>", "");
408     }
409 
testHeader()410     public void testHeader() {
411         sanitize("<header></header>", "<header></header>");
412     }
413 
testH1()414     public void testH1() {
415         sanitize("<h1>something</h1>", "<h1>something</h1>");
416         sanitize("<h1 align=\"left\">something</h1>", "<h1 align=\"left\">something</h1>");
417     }
418 
testH2()419     public void testH2() {
420         sanitize("<h2>something</h2>", "<h2>something</h2>");
421         sanitize("<h2 align=\"left\">something</h2>", "<h2 align=\"left\">something</h2>");
422     }
423 
testH3()424     public void testH3() {
425         sanitize("<h3>something</h3>", "<h3>something</h3>");
426         sanitize("<h3 align=\"left\">something</h3>", "<h3 align=\"left\">something</h3>");
427     }
428 
testH4()429     public void testH4() {
430         sanitize("<h4>something</h4>", "<h4>something</h4>");
431         sanitize("<h4 align=\"left\">something</h4>", "<h4 align=\"left\">something</h4>");
432     }
433 
testH5()434     public void testH5() {
435         sanitize("<h5>something</h5>", "<h5>something</h5>");
436         sanitize("<h5 align=\"left\">something</h5>", "<h5 align=\"left\">something</h5>");
437     }
438 
testH6()439     public void testH6() {
440         sanitize("<h6>something</h6>", "<h6>something</h6>");
441         sanitize("<h6 align=\"left\">something</h6>", "<h6 align=\"left\">something</h6>");
442     }
443 
testHr()444     public void testHr() {
445         sanitize("<hr/>", "<hr />");
446         sanitize("<hr align=\"left\"/>", "<hr align=\"left\" />");
447         sanitize("<hr noshade=\"noshade\"/>", "<hr noshade=\"noshade\" />");
448         sanitize("<hr size=\"11\"/>", "<hr size=\"11\" />");
449         sanitize("<hr width=\"666\"/>", "<hr width=\"666\" />");
450     }
451 
testHtml()452     public void testHtml() {
453         sanitize("<html></html>", "");
454         sanitize("<html xmlns=\"http://www.w3.org/1999/xhtml\"></html>", "");
455         sanitize("<html manifest=\"http://www.overhere.com/\"></html>", "");
456         sanitize("<html manifest=\"javascript:badness()\"></html>", "");
457     }
458 
testI()459     public void testI() {
460         sanitize("<i></i>", "<i></i>");
461     }
462 
testIframe()463     public void testIframe() {
464         sanitize("<iframe src=\"http://www.w3schools.com\"></iframe>", "");
465         sanitize("<iframe src=http://ha.ckers.org/scriptlet.html <", "");
466         sanitize("<iframe src=\"javascript:alert('XSS');\"></iframe>", "");
467         sanitize("<iframe src=# onmouseover=\"alert(document.cookie)\"></iframe>", "");
468     }
469 
testIsindex()470     public void testIsindex() {
471         sanitize("<isindex prompt=\"Search Document... \"/>", "");
472     }
473 
testImg()474     public void testImg() {
475         sanitize("<img/>", "");
476         sanitize("<img align=\"left\"/>", "<img align=\"left\" />");
477         sanitize("<img alt=\"something\"/>", "<img alt=\"something\" />");
478         sanitize("<img border=\"22\"/>", "<img border=\"22\" />");
479         sanitize("<img crossorigin=\"anonymous \"/>", "<img crossorigin=\"anonymous \" />");
480         sanitize("<img height=\"22\"/>", "<img height=\"22\" />");
481         sanitize("<img hspace=\"22\"/>", "<img hspace=\"22\" />");
482         sanitize("<img ismap=\"ismap\"/>", "<img ismap=\"ismap\" />");
483         sanitize("<img usemap=\"something\"/>", "<img usemap=\"something\" />");
484         sanitize("<img vspace=\"22\"/>", "<img vspace=\"22\" />");
485         sanitize("<img width=\"22\"/>", "<img width=\"22\" />");
486         sanitize("<img src=\"http://www.overhere.com/\"></img>",
487                 "<img src=\"http://www.overhere.com/\" />");
488         sanitize("<img longdesc=\"http://www.overhere.com/\"></img>",
489                 "<img longdesc=\"http://www.overhere.com/\" />");
490 
491         sanitize("<img src=\"javascript:badness()\"></img>", "");
492         sanitize("<img longdesc=\"javascript:badness()\"></img>", "");
493         sanitize("<img src=javascript:alert('XSS')>", "");
494         sanitize("<img src=JaVaScRiPt:alert('XSS')>", "");
495         sanitize("<img src=javascript:alert(\"XSS\")>", "");
496         sanitize("<img src=`javascript:alert(\"RSnake says, 'XSS'\")`>", "");
497         sanitize("<img \"\"\"><script>alert(\"XSS\")</script>\">", "&#34;&gt;");
498         sanitize("<img src=# onmouseover=\"alert('xxs')\">", "<img src=\"#\" />");
499         sanitize("<img src= onmouseover=\"alert('xxs')\">", "<img src=\"onmouseover&#61;\" />");
500         sanitize("<img onmouseover=\"alert('xxs')\">", "");
501         sanitize("<img src=/ onerror=\"alert(String.fromCharCode(88,83,83))\"></img>",
502                 "<img src=\"/\" />");
503         sanitize("<img src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;" +
504                 "&#108;&#101;&#114;&#116;&#40;\n&#39;&#88;&#83;&#83;&#39;&#41;>",
505                 "");
506         sanitize("<img src=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114" +
507                 "&#0000105&#0000112&#0000116&#0000058&#0000097&\n" +
508                 "#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083" +
509                 "&#0000039&#0000041>", "");
510         sanitize("<img src=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65" +
511                 "&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>", "");
512         sanitize("<img src=\"jav\tascript:alert('XSS');\">", "");
513         sanitize("<img src=\"jav&#x09;ascript:alert('XSS');\">", "");
514         sanitize("<img src=\"jav&#x0A;ascript:alert('XSS');\">", "");
515         sanitize("<img src=\"jav&#x0D;ascript:alert('XSS');\">", "");
516         sanitize("<img src=java\0script:alert(\\\"XSS\\\")>", "");
517         sanitize("<img src=\" &#14;  javascript:alert('XSS');\">", "");
518         sanitize("<img src=\"javascript:alert('XSS')\"", "");
519         sanitize("<img dynsrc=\"javascript:alert('XSS')\">", "");
520         sanitize("<img lowsrc=\"javascript:alert('XSS')\">", "");
521         sanitize("<img src='vbscript:msgbox(\"XSS\")'>", "");
522         sanitize("<img src=\"livescript:[code]\">", "");
523         sanitize("<img style=\"xss:expr/*XSS*/ession(alert('XSS'))\">", "");
524     }
525 
testInput()526     public void testInput() {
527         sanitize("<input accept=\"image/*\"/>", "<input accept=\"image/*\" />");
528         sanitize("<input align=\"left\"/>", "<input align=\"left\" />");
529         sanitize("<input alt=\"something\"/>", "<input alt=\"something\" />");
530         sanitize("<input autocomplete=\"on\"/>", "<input autocomplete=\"on\" />");
531         sanitize("<input autofocus=\"autofocus\"/>", "<input autofocus=\"autofocus\" />");
532         sanitize("<input checked=\"checked\"/>", "<input checked=\"checked\" />");
533         sanitize("<input disabled=\"disabled\"/>", "<input disabled=\"disabled\" />");
534         sanitize("<input form=\"1\"/>", "<input form=\"1\" />");
535         sanitize("<input formenctype=\"text/plain\"/>", "<input formenctype=\"text/plain\" />");
536         sanitize("<input formmethod=\"post\"/>", "<input formmethod=\"post\" />");
537         sanitize("<input formnovalidate=\"formnovalidate\"/>",
538                 "<input formnovalidate=\"formnovalidate\" />");
539         sanitize("<input formtarget=\"_top\"/>", "<input formtarget=\"_top\" />");
540         sanitize("<input height=\"22\"/>", "<input height=\"22\" />");
541         sanitize("<input list=\"something\"/>", "<input list=\"something\" />");
542         sanitize("<input max=\"1000\"/>", "<input max=\"1000\" />");
543         sanitize("<input maxlength=\"10\"/>", "<input maxlength=\"10\" />");
544         sanitize("<input min=\"10\"/>", "<input min=\"10\" />");
545         sanitize("<input multiple=\"multiple\"/>", "<input multiple=\"multiple\" />");
546         sanitize("<input name=\"herman\"/>", "<input name=\"herman\" />");
547         sanitize("<input pattern=\"*.*\"/>", "<input pattern=\"*.*\" />");
548         sanitize("<input placeholder=\"something\"/>", "<input placeholder=\"something\" />");
549         sanitize("<input readonly=\"readonly\"/>", "<input readonly=\"readonly\" />");
550         sanitize("<input required=\"required\"/>", "<input required=\"required\" />");
551         sanitize("<input size=\"22\"/>", "<input size=\"22\" />");
552         sanitize("<input step=\"5\"/>", "<input step=\"5\" />");
553         sanitize("<input type=\"button\"/>", "<input type=\"button\" />");
554         sanitize("<input value=\"something\"/>", "<input value=\"something\" />");
555         sanitize("<input width=\"50\"/>", "<input width=\"50\" />");
556         sanitize("<input src=\"http://www.overhere.com/\"></input>",
557                 "<input src=\"http://www.overhere.com/\" />");
558         sanitize("<input formaction=\"http://www.overhere.com/\"></input>",
559                 "<input formaction=\"http://www.overhere.com/\" />");
560 
561         sanitize("<input src=\"javascript:badness()\"></input>", "");
562         sanitize("<input formaction=\"javascript:badness()\"></input>", "");
563         sanitize("<input type=\"image\" src=\"javascript:alert('XSS');\">",
564                 "<input type=\"image\" />");
565         sanitize("<input type=\"text\" onchange=\"javascript:alert('XSS');\">",
566                 "<input type=\"text\" />");
567         sanitize("<input type=\"button\" onclick=\"javascript:alert('XSS');\">",
568                 "<input type=\"button\" />");
569         sanitize("<input type=\"button\" ondblclick=\"javascript:alert('XSS');\">",
570                 "<input type=\"button\" />");
571     }
572 
testIns()573     public void testIns() {
574         sanitize("<ins>something</ins>", "<ins>something</ins>");
575         sanitize("<ins cite=\"javascript:badness();\">something</ins>", "<ins>something</ins>");
576         sanitize("<ins cite=\"http://www.reason.com/\">something</ins>",
577                 "<ins cite=\"http://www.reason.com/\">something</ins>");
578         sanitize("<ins datetime=\"something\">something</ins>",
579                 "<ins datetime=\"something\">something</ins>");
580     }
581 
testKbd()582     public void testKbd() {
583         sanitize("<kbd>something</kbd>", "<kbd>something</kbd>");
584     }
585 
testKeygen()586     public void testKeygen() {
587         sanitize("<keygen/>", "<keygen />");
588         sanitize("<keygen autofocus=\"autofocus\"/>", "<keygen autofocus=\"autofocus\" />");
589         sanitize("<keygen challenge=\"challenge\"/>", "<keygen challenge=\"challenge\" />");
590         sanitize("<keygen disabled=\"disabled\"/>", "<keygen disabled=\"disabled\" />");
591         sanitize("<keygen form=\"formId\"/>", "<keygen form=\"formId\" />");
592         sanitize("<keygen keytype=\"rsa\"/>", "<keygen keytype=\"rsa\" />");
593         sanitize("<keygen name=\"herman\"/>", "<keygen name=\"herman\" />");
594     }
595 
testLabel()596     public void testLabel() {
597         sanitize("<label for=\"elementId\">Something:</label>", "<label>Something:</label>");
598         sanitize("<label form=\"formId\">Something:</label>",
599                 "<label form=\"formId\">Something:</label>");
600     }
601 
testLegend()602     public void testLegend() {
603         sanitize("<legend>Something:</legend>", "<legend>Something:</legend>");
604         sanitize("<legend align=\"left\">Something:</legend>",
605                 "<legend align=\"left\">Something:</legend>");
606     }
607 
testLi()608     public void testLi() {
609         sanitize("<li>Something:</li>", "<li>Something:</li>");
610         sanitize("<li type=\"a\">Something:</li>", "<li type=\"a\">Something:</li>");
611         sanitize("<li value=\"11\">Something:</li>", "<li value=\"11\">Something:</li>");
612     }
613 
testLink()614     public void testLink() {
615         sanitize("<link charset=\"utf8\"/>", "");
616         sanitize("<link href=\"http://www.reason.com/\"/>", "");
617         sanitize("<link hreflang=\"fr_CA\"/>", "");
618         sanitize("<link media=\"tv\"/>", "");
619         sanitize("<link rel=\"alternate\"/>", "");
620         sanitize("<link rev=\"something\"/>", "");
621         sanitize("<link sizes=\"500x400\"/>", "");
622         sanitize("<link target=\"_top\"/>", "");
623         sanitize("<link type=\"mimeType\"/>", "");
624         sanitize("<link href=\"javascript:alert('XSS');\">", "");
625     }
626 
testMain()627     public void testMain() {
628         sanitize("<main>something</main>", "<main>something</main>");
629     }
630 
testMap()631     public void testMap() {
632         sanitize("<map></map>", "<map></map>");
633         sanitize("<map name=\"mapname\"></map>", "<map name=\"mapname\"></map>");
634     }
635 
testMark()636     public void testMark() {
637         sanitize("<mark>something</mark>", "<mark>something</mark>");
638     }
639 
testMenu()640     public void testMenu() {
641         sanitize("<menu></menu>", "<menu></menu>");
642         sanitize("<menu label=\"Edit\"></menu>", "<menu label=\"Edit\"></menu>");
643         sanitize("<menu type=\"popup\"></menu>", "<menu type=\"popup\"></menu>");
644     }
645 
testMenuitem()646     public void testMenuitem() {
647         sanitize("<menuitem></menuitem>", "<menuitem></menuitem>");
648         sanitize("<menuitem checked=\"checked\"></menuitem>",
649                 "<menuitem checked=\"checked\"></menuitem>");
650         sanitize("<menuitem command=\"something\"></menuitem>",
651                 "<menuitem command=\"something\"></menuitem>");
652         sanitize("<menuitem default=\"default\"></menuitem>",
653                 "<menuitem default=\"default\"></menuitem>");
654         sanitize("<menuitem disabled=\"disabled\"></menuitem>",
655                 "<menuitem disabled=\"disabled\"></menuitem>");
656         sanitize("<menuitem icon=\"http://www.reason.com/\"></menuitem>",
657                 "<menuitem icon=\"http://www.reason.com/\"></menuitem>");
658         sanitize("<menuitem label=\"something\"></menuitem>",
659                 "<menuitem label=\"something\"></menuitem>");
660         sanitize("<menuitem type=\"checkbox\"></menuitem>",
661                 "<menuitem type=\"checkbox\"></menuitem>");
662         sanitize("<menuitem radiogroup=\"something\"></menuitem>",
663                 "<menuitem radiogroup=\"something\"></menuitem>");
664 
665         sanitize("<menuitem icon=\"javascript:badness()\"></menuitem>", "<menuitem></menuitem>");
666     }
667 
testMeta()668     public void testMeta() {
669         sanitize("<meta/>", "");
670         sanitize("<meta charset=\"utf8\" />", "");
671         sanitize("<meta content=\"something\" />", "");
672         sanitize("<meta http-equiv=\"refresh\" />", "");
673         sanitize("<meta name=\"description\" />", "");
674         sanitize("<meta scheme=\"YYYY-MM-DD\" />", "");
675         sanitize("<meta http-equiv=\"Link\" content=\"<http://ha.ckers.org/xss.css>; " +
676                 "REL=stylesheet\">", "");
677         sanitize("<meta http-equiv=\"refresh\" content=\"0;url=javascript:alert('XSS');\">", "");
678         sanitize("<meta http-equiv=\"refresh\" content=\"0;url=data:text/html " +
679                 "base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K\">", "");
680         sanitize("<meta http-equiv=\"refresh\" CONTENT=\"0; url=http://;" +
681                 "URL=javascript:alert('XSS');\">", "");
682     }
683 
testMeter()684     public void testMeter() {
685         sanitize("<meter>2 out of 10</meter>", "<meter>2 out of 10</meter>");
686         sanitize("<meter form=\"formId\">2 out of 10</meter>",
687                 "<meter form=\"formId\">2 out of 10</meter>");
688         sanitize("<meter high=\"10\">2 out of 10</meter>",
689                 "<meter high=\"10\">2 out of 10</meter>");
690         sanitize("<meter low=\"10\">2 out of 10</meter>", "<meter low=\"10\">2 out of 10</meter>");
691         sanitize("<meter max=\"10\">2 out of 10</meter>", "<meter max=\"10\">2 out of 10</meter>");
692         sanitize("<meter min=\"10\">2 out of 10</meter>", "<meter min=\"10\">2 out of 10</meter>");
693         sanitize("<meter optimum=\"10\">2 out of 10</meter>",
694                 "<meter optimum=\"10\">2 out of 10</meter>");
695         sanitize("<meter value=\"10\">2 out of 10</meter>",
696                 "<meter value=\"10\">2 out of 10</meter>");
697     }
698 
testNav()699     public void testNav() {
700         sanitize("<nav>something</nav>", "<nav>something</nav>");
701     }
702 
testNoframes()703     public void testNoframes() {
704         sanitize("<noframes>No frames!</noframes>", "");
705     }
706 
testNoscript()707     public void testNoscript() {
708         sanitize("<noscript>No JavaScript!</noscript>", "");
709     }
710 
testObject()711     public void testObject() {
712         sanitize("<object>No Objects!</object>", "");
713         sanitize("<object type=\"text/x-scriptlet\" data=\"http://ha.ckers.org/scriptlet.html\">" +
714                 "</object>", "");
715     }
716 
testOl()717     public void testOl() {
718         sanitize("<ol></ol>", "<ol></ol>");
719         sanitize("<ol compact=\"compact\"></ol>", "<ol compact=\"compact\"></ol>");
720         sanitize("<ol reversed=\"reversed\"></ol>", "<ol reversed=\"reversed\"></ol>");
721         sanitize("<ol start=\"11\"></ol>", "<ol start=\"11\"></ol>");
722         sanitize("<ol type=\"a\"></ol>", "<ol type=\"a\"></ol>");
723     }
724 
testOptgroup()725     public void testOptgroup() {
726         sanitize("<optgroup></optgroup>", "<optgroup></optgroup>");
727         sanitize("<optgroup disabled=\"disabled\"></optgroup>",
728                 "<optgroup disabled=\"disabled\"></optgroup>");
729         sanitize("<optgroup label=\"something\"></optgroup>",
730                 "<optgroup label=\"something\"></optgroup>");
731     }
732 
testOption()733     public void testOption() {
734         sanitize("<option>something</option>", "<option>something</option>");
735         sanitize("<option disabled=\"disabled\">something</option>",
736                 "<option disabled=\"disabled\">something</option>");
737         sanitize("<option label=\"something\">something</option>",
738                 "<option label=\"something\">something</option>");
739         sanitize("<option selected=\"selected\">something</option>",
740                 "<option selected=\"selected\">something</option>");
741         sanitize("<option value=\"volvo\">something</option>",
742                 "<option value=\"volvo\">something</option>");
743     }
744 
testOutput()745     public void testOutput() {
746         sanitize("<output></output>", "<output></output>");
747         sanitize("<output for=\"elementId\"></output>", "<output></output>");
748         sanitize("<output form=\"formId\"></output>", "<output form=\"formId\"></output>");
749         sanitize("<output name=\"something\"></output>", "<output name=\"something\"></output>");
750     }
751 
testP()752     public void testP() {
753         sanitize("<p>something</p>", "<p>something</p>");
754         sanitize("<p align=\"left\">something</p>", "<p align=\"left\">something</p>");
755     }
756 
testParam()757     public void testParam() {
758         sanitize("<param name=\"autoplay\" value=\"true\">", "");
759     }
760 
testPre()761     public void testPre() {
762         sanitize("<pre>something</pre>", "<pre>something</pre>");
763         sanitize("<pre width=\"400\">something</pre>", "<pre width=\"400\">something</pre>");
764     }
765 
testProgress()766     public void testProgress() {
767         sanitize("<progress></progress>", "<progress></progress>");
768         sanitize("<progress value=\"22\"></progress>", "<progress value=\"22\"></progress>");
769         sanitize("<progress max=\"100\"></progress>", "<progress max=\"100\"></progress>");
770     }
771 
testQ()772     public void testQ() {
773         sanitize("<q>something</q>", "<q>something</q>");
774         sanitize("<q cite=\"http://www.reason.com/\">something</q>",
775                 "<q cite=\"http://www.reason.com/\">something</q>");
776         sanitize("<q cite=\"javascript:badness()\">something</q>", "<q>something</q>");
777     }
778 
testRp()779     public void testRp() {
780         sanitize("<rp>something</rp>", "<rp>something</rp>");
781     }
782 
testRt()783     public void testRt() {
784         sanitize("<rt>something</rt>", "<rt>something</rt>");
785     }
786 
testRuby()787     public void testRuby() {
788         sanitize("<ruby></ruby>", "<ruby></ruby>");
789     }
790 
testS()791     public void testS() {
792         sanitize("<s>old skool strikethrough</s>", "<s>old skool strikethrough</s>");
793     }
794 
testSamp()795     public void testSamp() {
796         sanitize("<samp>something</samp>", "<samp>something</samp>");
797     }
798 
testScript()799     public void testScript() {
800         sanitize("<script>malicious script</script>", "");
801         sanitize("<<script>alert(\"XSS\");//<</script>", "&lt;");
802         sanitize("<script src=http://ha.ckers.org/xss.js></script>", "");
803         sanitize("<script/XSS src=\"http://ha.ckers.org/xss.js\"></script>", "");
804         sanitize("<script/src=\"http://ha.ckers.org/xss.js\"></script>", "");
805         sanitize("<script src=http://ha.ckers.org/xss.js?< B >", "");
806         sanitize("<script src=//ha.ckers.org/.j>", "");
807         sanitize("</title><script>alert(\"XSS\");</script>", "");
808         sanitize("<script src=\"http://ha.ckers.org/xss.jpg\"></script>", "");
809 
810         String attack = "';alert(String.fromCharCode(88,83,83))//';" +
811                 "alert(String.fromCharCode(88,83,83))//\";\n" +
812                 "alert(String.fromCharCode(88,83,83))//\";" +
813                 "alert(String.fromCharCode(88,83,83))//--\n" +
814                 "></SCRIPT>\">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>";
815         String defend = "&#39;;alert(String.fromCharCode(88,83,83))//&#39;;" +
816                 "alert(String.fromCharCode(88,83,83))//&#34;;\n" +
817                 "alert(String.fromCharCode(88,83,83))//&#34;;" +
818                 "alert(String.fromCharCode(88,83,83))//--\n" +
819                 "&gt;&#34;&gt;&#39;&gt;";
820         sanitize(attack, defend);
821     }
822 
testSection()823     public void testSection() {
824         sanitize("<section>something</section>", "<section>something</section>");
825     }
826 
testSelect()827     public void testSelect() {
828         sanitize("<select></select>", "<select></select>");
829         sanitize("<select autofocus=\"autofocus\"></select>",
830                 "<select autofocus=\"autofocus\"></select>");
831         sanitize("<select disabled=\"disabled\"></select>",
832                 "<select disabled=\"disabled\"></select>");
833         sanitize("<select form=\"formId\"></select>", "<select form=\"formId\"></select>");
834         sanitize("<select multiple=\"multiple\"></select>",
835                 "<select multiple=\"multiple\"></select>");
836         sanitize("<select required=\"required\"></select>",
837                 "<select required=\"required\"></select>");
838         sanitize("<select size=\"11\"></select>", "<select size=\"11\"></select>");
839     }
840 
testSmall()841     public void testSmall() {
842         sanitize("<small>something</small>", "<small>something</small>");
843     }
844 
testSource()845     public void testSource() {
846         sanitize("<source/>", "<source />");
847         sanitize("<source media=\"something\"/>", "<source media=\"something\" />");
848         sanitize("<source type=\"mimeType\"/>", "<source type=\"mimeType\" />");
849         sanitize("<source src=\"http://www.reason.com/\"/source>",
850                 "<source src=\"http://www.reason.com/\" />");
851         sanitize("<source src=\"javascript:badness()\"/source>", "<source />");
852     }
853 
testSpan()854     public void testSpan() {
855         sanitize("<span style=\"color:blue\">something</span>",
856                 "<span style=\"color:blue\">something</span>");
857     }
858 
testStrike()859     public void testStrike() {
860         sanitize("<strike>something</strike>", "<strike>something</strike>");
861     }
862 
testStrong()863     public void testStrong() {
864         sanitize("<strong>something</strong>", "<strong>something</strong>");
865     }
866 
testStyle()867     public void testStyle() {
868         sanitize("<style>something</style>", "");
869         sanitize("<style media=\"something\">something</style>", "");
870         sanitize("<style scoped=\"scoped\">something</style>", "");
871         sanitize("<style type=\"text/css\">something</style>", "");
872         sanitize("<style>li {list-style-image: url(\"javascript:alert('XSS')\");}</style>", "");
873         sanitize("<style>@im\\port'\\ja\\vasc\\ript:alert(\"XSS\")';</style>", "");
874         sanitize("<style>body{-moz-binding:url(\"http://ha.ckers.org/xssmoz.xml#xss\")}</style>",
875                 "");
876         sanitize("<style>@import'http://ha.ckers.org/xss.css';</style>", "");
877         sanitize("<style type=\"text/javascript\">alert('XSS');</style>", "");
878         sanitize("<style>.XSS{background-image:url(\"javascript:alert('XSS')\");}</style>" +
879                 "<a class=XSS></a>", "");
880         sanitize("<style type=\"text/css\">body{background:url(\"javascript:alert('XSS')\")}" +
881                 "</style>", "");
882     }
883 
testSub()884     public void testSub() {
885         sanitize("<sub>something</sub>", "<sub>something</sub>");
886     }
887 
testSummary()888     public void testSummary() {
889         sanitize("<summary>something</summary>", "<summary>something</summary>");
890     }
891 
testSup()892     public void testSup() {
893         sanitize("<sup>something</sup>", "<sup>something</sup>");
894     }
895 
testTable()896     public void testTable() {
897         sanitize("<table></table>", "<table></table>");
898         sanitize("<table align=\"left\"></table>", "<table align=\"left\"></table>");
899         sanitize("<table bgcolor=\"red\"></table>", "<table bgcolor=\"red\"></table>");
900         sanitize("<table border=\"1\"></table>", "<table border=\"1\"></table>");
901         sanitize("<table cellpadding=\"1\"></table>", "<table cellpadding=\"1\"></table>");
902         sanitize("<table cellspacing=\"1\"></table>", "<table cellspacing=\"1\"></table>");
903         sanitize("<table frame=\"void\"></table>", "<table frame=\"void\"></table>");
904         sanitize("<table rules=\"none\"></table>", "<table rules=\"none\"></table>");
905         sanitize("<table sortable=\"sortable\"></table>", "<table sortable=\"sortable\"></table>");
906         sanitize("<table summary=\"something\"></table>", "<table summary=\"something\"></table>");
907         sanitize("<table width=\"11\"></table>", "<table width=\"11\"></table>");
908 
909         sanitize("<table background=\"javascript:alert('XSS')\">", "<table></table>");
910     }
911 
testTbody()912     public void testTbody() {
913         sanitize("<tbody></tbody>", "<tbody></tbody>");
914         sanitize("<tbody char=\"something\"></tbody>", "<tbody char=\"something\"></tbody>");
915         sanitize("<tbody charoff=\"11\"></tbody>", "<tbody charoff=\"11\"></tbody>");
916         sanitize("<tbody valign=\"top\"></tbody>", "<tbody valign=\"top\"></tbody>");
917     }
918 
testTd()919     public void testTd() {
920         sanitize("<td></td>", "<td></td>");
921         sanitize("<td abbr=\"something\"></td>", "<td abbr=\"something\"></td>");
922         sanitize("<td align=\"left\"></td>", "<td align=\"left\"></td>");
923         sanitize("<td axis=\"something\"></td>", "<td axis=\"something\"></td>");
924         sanitize("<td bgcolor=\"red\"></td>", "<td bgcolor=\"red\"></td>");
925         sanitize("<td char=\"something\"></td>", "<td char=\"something\"></td>");
926         sanitize("<td charoff=\"22\"></td>", "<td charoff=\"22\"></td>");
927         sanitize("<td colspan=\"33\"></td>", "<td colspan=\"33\"></td>");
928         sanitize("<td height=\"44\"></td>", "<td height=\"44\"></td>");
929         sanitize("<td nowrap=\"nowrap\"></td>", "<td nowrap=\"nowrap\"></td>");
930         sanitize("<td rowspan=\"3\"></td>", "<td rowspan=\"3\"></td>");
931         sanitize("<td scope=\"col\"></td>", "<td scope=\"col\"></td>");
932         sanitize("<td valign=\"top\"></td>", "<td valign=\"top\"></td>");
933         sanitize("<td width=\"55\"></td>", "<td width=\"55\"></td>");
934 
935         sanitize("<td headers=\"headerId\"></td>", "<td></td>");
936         sanitize("<td background=\"javascript:alert('XSS')\">", "<td></td>");
937     }
938 
testTextarea()939     public void testTextarea() {
940         sanitize("<textarea></textarea>", "<textarea></textarea>");
941         sanitize("<textarea autofocus=\"autofocus\"></textarea>",
942                 "<textarea autofocus=\"autofocus\"></textarea>");
943         sanitize("<textarea cols=\"1\"></textarea>", "<textarea cols=\"1\"></textarea>");
944         sanitize("<textarea disabled=\"disabled\"></textarea>",
945                 "<textarea disabled=\"disabled\"></textarea>");
946         sanitize("<textarea form=\"formId\"></textarea>", "<textarea form=\"formId\"></textarea>");
947         sanitize("<textarea maxlength=\"2\"></textarea>", "<textarea maxlength=\"2\"></textarea>");
948         sanitize("<textarea name=\"something\"></textarea>",
949                 "<textarea name=\"something\"></textarea>");
950         sanitize("<textarea placeholder=\"something\"></textarea>",
951                 "<textarea placeholder=\"something\"></textarea>");
952         sanitize("<textarea readonly=\"readonly\"></textarea>",
953                 "<textarea readonly=\"readonly\"></textarea>");
954         sanitize("<textarea required=\"required\"></textarea>",
955                 "<textarea required=\"required\"></textarea>");
956         sanitize("<textarea rows=\"3\"></textarea>", "<textarea rows=\"3\"></textarea>");
957         sanitize("<textarea wrap=\"soft\"></textarea>", "<textarea wrap=\"soft\"></textarea>");
958     }
959 
testTfoot()960     public void testTfoot() {
961         sanitize("<tfoot></tfoot>", "<tfoot></tfoot>");
962         sanitize("<tfoot align=\"left\"></tfoot>", "<tfoot align=\"left\"></tfoot>");
963         sanitize("<tfoot char=\"something\"></tfoot>", "<tfoot char=\"something\"></tfoot>");
964         sanitize("<tfoot charoff=\"1\"></tfoot>", "<tfoot charoff=\"1\"></tfoot>");
965         sanitize("<tfoot valign=\"top\"></tfoot>", "<tfoot valign=\"top\"></tfoot>");
966     }
967 
testTh()968     public void testTh() {
969         sanitize("<th></th>", "<th></th>");
970         sanitize("<th abbr=\"something\"></th>", "<th abbr=\"something\"></th>");
971         sanitize("<th align=\"left\"></th>", "<th align=\"left\"></th>");
972         sanitize("<th axis=\"something\"></th>", "<th axis=\"something\"></th>");
973         sanitize("<th bgcolor=\"red\"></th>", "<th bgcolor=\"red\"></th>");
974         sanitize("<th char=\"something\"></th>", "<th char=\"something\"></th>");
975         sanitize("<th charoff=\"22\"></th>", "<th charoff=\"22\"></th>");
976         sanitize("<th colspan=\"33\"></th>", "<th colspan=\"33\"></th>");
977         sanitize("<th height=\"44\"></th>", "<th height=\"44\"></th>");
978         sanitize("<th nowrap=\"nowrap\"></th>", "<th nowrap=\"nowrap\"></th>");
979         sanitize("<th rowspan=\"3\"></th>", "<th rowspan=\"3\"></th>");
980         sanitize("<th scope=\"col\"></th>", "<th scope=\"col\"></th>");
981         sanitize("<th sorted=\"reversed\"></th>", "<th sorted=\"reversed\"></th>");
982         sanitize("<th valign=\"top\"></th>", "<th valign=\"top\"></th>");
983         sanitize("<th width=\"55\"></th>", "<th width=\"55\"></th>");
984 
985         sanitize("<th headers=\"headerId\"></th>", "<th></th>");
986     }
987 
testThead()988     public void testThead() {
989         sanitize("<thead></thead>", "<thead></thead>");
990         sanitize("<thead align=\"left\"></thead>", "<thead align=\"left\"></thead>");
991         sanitize("<thead char=\"something\"></thead>", "<thead char=\"something\"></thead>");
992         sanitize("<thead charoff=\"1\"></thead>", "<thead charoff=\"1\"></thead>");
993         sanitize("<thead valign=\"top\"></thead>", "<thead valign=\"top\"></thead>");
994     }
995 
testTime()996     public void testTime() {
997         sanitize("<time></time>", "<time></time>");
998         sanitize("<time datetime=\"datetime\"></time>", "<time datetime=\"datetime\"></time>");
999     }
1000 
testTitle()1001     public void testTitle() {
1002         sanitize("<title>something</title>", "");
1003     }
1004 
testTr()1005     public void testTr() {
1006         sanitize("<tr></tr>", "<tr></tr>");
1007         sanitize("<tr align=\"left\"></tr>", "<tr align=\"left\"></tr>");
1008         sanitize("<tr bgcolor=\"red\"></tr>", "<tr bgcolor=\"red\"></tr>");
1009         sanitize("<tr char=\"something\"></tr>", "<tr char=\"something\"></tr>");
1010         sanitize("<tr charoff=\"1\"></tr>", "<tr charoff=\"1\"></tr>");
1011         sanitize("<tr valign=\"top\"></tr>", "<tr valign=\"top\"></tr>");
1012     }
1013 
testTrack()1014     public void testTrack() {
1015         sanitize("<track/>", "<track />");
1016         sanitize("<track default=\"default\"/>", "<track default=\"default\" />");
1017         sanitize("<track kind=\"captions\"/>", "<track kind=\"captions\" />");
1018         sanitize("<track label=\"something\"/>", "<track label=\"something\" />");
1019         sanitize("<track src=\"http://www.reason.com/\"/>",
1020                 "<track src=\"http://www.reason.com/\" />");
1021         sanitize("<track srclang=\"fr_CA\"/>", "<track srclang=\"fr_CA\" />");
1022 
1023         sanitize("<track src=\"javascript:badness()\"/>", "<track />");
1024     }
1025 
testTt()1026     public void testTt() {
1027         sanitize("<tt>something</tt>", "<tt>something</tt>");
1028     }
1029 
testU()1030     public void testU() {
1031         sanitize("<u>something</u>", "<u>something</u>");
1032     }
1033 
testUl()1034     public void testUl() {
1035         sanitize("<ul compact=\"compact\"></ul>", "<ul compact=\"compact\"></ul>");
1036         sanitize("<ul type=\"disc\"></ul>", "<ul type=\"disc\"></ul>");
1037     }
1038 
testVar()1039     public void testVar() {
1040         sanitize("<var>something</var>", "<var>something</var>");
1041     }
1042 
testVideo()1043     public void testVideo() {
1044         sanitize("<video></video>", "");
1045     }
1046 
testWbr()1047     public void testWbr() {
1048         sanitize("word1<wbr/>word2", "word1<wbr />word2");
1049     }
1050 
sanitize(String dirtyHTML, String expectedHTML)1051     private void sanitize(String dirtyHTML, String expectedHTML) {
1052         final String cleansedHTML = HtmlSanitizer.sanitizeHtml(dirtyHTML);
1053         assertEquals(expectedHTML, cleansedHTML);
1054     }
1055 }
1056