TYPO3 API  SVNRelease
removexssTest.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009-2011 Steffen Kamper <info@sk-typo3.de>
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 
00025 require_once(PATH_typo3 . 'contrib/RemoveXSS/RemoveXSS.php');
00026 
00027 /**
00028  * Testcase for class RemoveXSS
00029  *
00030  * @author  Steffen Kamper <info@sk-typo3.de>
00031  * @package TYPO3
00032  * @subpackage contrib
00033  * @ see http://ha.ckers.org/xss.html
00034  * @ examples from http://ha.ckers.org/xssAttacks.xml
00035  */
00036 class RemoveXSSTest extends tx_phpunit_testcase {
00037 
00038     /**
00039      * @test
00040      */
00041     public function checkAttackScriptAlert() {
00042         $testString = "<SCRIPT>alert('XSS')</SCRIPT>";
00043         $expectedString = "<sc<x>ript>alert('XSS')</SCRIPT>";
00044         $actualString = RemoveXSS::process($testString);
00045 
00046         $this->assertEquals($expectedString, $actualString);
00047     }
00048     /**
00049      * @test
00050      */
00051     public function checkAttackScriptSrcJs() {
00052         $testString = '<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>';
00053         $expectedString = "<sc<x>ript SRC=http://ha.ckers.org/xss.js></SCRIPT>";
00054         $actualString = RemoveXSS::process($testString);
00055 
00056         $this->assertEquals($expectedString, $actualString);
00057     }
00058     /**
00059      * @test
00060      */
00061     public function checkAttackScriptAlertFromCharCode() {
00062         $testString = '<SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>';
00063         $expectedString = '<sc<x>ript>alert(String.fromCharCode(88,83,83))</SCRIPT>';
00064         $actualString = RemoveXSS::process($testString);
00065 
00066         $this->assertEquals($expectedString, $actualString);
00067     }
00068     /**
00069      * @test
00070      */
00071     public function checkAttackBaseHref() {
00072         $testString = "<BASE HREF=\"javascript:alert('XSS');//\">";
00073         $expectedString = "<ba<x>se HREF=\"ja<x>vascript:alert('XSS');//\">";
00074         $actualString = RemoveXSS::process($testString);
00075 
00076         $this->assertEquals($expectedString, $actualString);
00077     }
00078     /**
00079      * @test
00080      */
00081     public function checkAttackBgsound() {
00082         $testString = "<BGSOUND SRC=\"javascript:alert('XSS');\">";
00083         $expectedString = "<bg<x>sound SRC=\"ja<x>vascript:alert('XSS');\">";
00084         $actualString = RemoveXSS::process($testString);
00085 
00086         $this->assertEquals($expectedString, $actualString);
00087     }
00088     /**
00089      * @test
00090      */
00091     public function checkAttackBodyBackground() {
00092         $testString = "<BODY BACKGROUND=\"javascript:alert('XSS');\">";
00093         $expectedString = "<BODY BACKGROUND=\"ja<x>vascript:alert('XSS');\">";
00094         $actualString = RemoveXSS::process($testString);
00095 
00096         $this->assertEquals($expectedString, $actualString);
00097     }
00098     /**
00099      * @test
00100      */
00101     public function checkAttackBodyOnLoad() {
00102         $testString = "<BODY ONLOAD=alert('XSS')>";
00103         $expectedString = "<BODY on<x>load=alert('XSS')>";
00104         $actualString = RemoveXSS::process($testString);
00105 
00106         $this->assertEquals($expectedString, $actualString);
00107     }
00108     /**
00109      * @test
00110      */
00111     public function checkAttackStyleUrl() {
00112         $testString = "<DIV STYLE=\"background-image: url(javascript:alert('XSS'))\">";
00113         $expectedString = "<DIV st<x>yle=\"background-image: url(ja<x>vascript:alert('XSS'))\">";
00114         $actualString = RemoveXSS::process($testString);
00115 
00116         $this->assertEquals($expectedString, $actualString);
00117     }
00118     /**
00119      * @test
00120      */
00121     public function checkAttackStyleWidth() {
00122         $testString = "<DIV STYLE=\"width: expression(alert('XSS'));\">";
00123         $expectedString = "<DIV st<x>yle=\"width: expression(alert('XSS'));\">";
00124         $actualString = RemoveXSS::process($testString);
00125 
00126         $this->assertEquals($expectedString, $actualString);
00127     }
00128     /**
00129      * @test
00130      */
00131     public function checkAttackFrameset() {
00132         $testString = "<FRAMESET><FRAME SRC=\"javascript:alert('XSS');\"></FRAMESET>";
00133         $expectedString = "<fr<x>ameset><fr<x>ame SRC=\"ja<x>vascript:alert('XSS');\"></FRAMESET>";
00134         $actualString = RemoveXSS::process($testString);
00135 
00136         $this->assertEquals($expectedString, $actualString);
00137     }
00138     /**
00139      * @test
00140      */
00141     public function checkAttackIframe() {
00142         $testString = "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>";
00143         $expectedString = "<if<x>rame SRC=\"ja<x>vascript:alert('XSS');\"></IFRAME>";
00144         $actualString = RemoveXSS::process($testString);
00145 
00146         $this->assertEquals($expectedString, $actualString);
00147     }
00148     /**
00149      * @test
00150      */
00151     public function checkAttackInputImage() {
00152         $testString = "<INPUT TYPE=\"IMAGE\" SRC=\"javascript:alert('XSS');\">";
00153         $expectedString = "<INPUT TYPE=\"IMAGE\" SRC=\"ja<x>vascript:alert('XSS');\">";
00154         $actualString = RemoveXSS::process($testString);
00155 
00156         $this->assertEquals($expectedString, $actualString);
00157     }
00158     /**
00159      * @test
00160      */
00161     public function checkAttackImageSrc() {
00162         $testString = "<IMG SRC=\"javascript:alert('XSS');\">";
00163         $expectedString = "<IMG SRC=\"ja<x>vascript:alert('XSS');\">";
00164         $actualString = RemoveXSS::process($testString);
00165 
00166         $this->assertEquals($expectedString, $actualString);
00167     }
00168     /**
00169      * @test
00170      */
00171     public function checkAttackImageSrcNoQuotesNoSemicolon() {
00172         $testString = "<IMG SRC=javascript:alert('XSS')>";
00173         $expectedString = "<IMG SRC=ja<x>vascript:alert('XSS')>";
00174         $actualString = RemoveXSS::process($testString);
00175 
00176         $this->assertEquals($expectedString, $actualString);
00177     }
00178     /**
00179      * @test
00180      */
00181     public function checkAttackImageDynsrc() {
00182         $testString = "<IMG DYNSRC=\"javascript:alert('XSS');\">";
00183         $expectedString = "<IMG DYNSRC=\"ja<x>vascript:alert('XSS');\">";
00184         $actualString = RemoveXSS::process($testString);
00185 
00186         $this->assertEquals($expectedString, $actualString);
00187     }
00188     /**
00189      * @test
00190      */
00191     public function checkAttackImageLowsrc() {
00192         $testString = "<IMG LOWSRC=\"javascript:alert('XSS');\">";
00193         $expectedString = "<IMG LOWSRC=\"ja<x>vascript:alert('XSS');\">";
00194         $actualString = RemoveXSS::process($testString);
00195 
00196         $this->assertEquals($expectedString, $actualString);
00197     }
00198     /**
00199      * @test
00200      */
00201     public function checkAttackStyle() {
00202         $testString = "<STYLE>li {list-style-image: url(\"javascript:alert('XSS')\");}</STYLE>";
00203         $expectedString = "<st<x>yle>li {list-style-image: url(\"ja<x>vascript:alert('XSS')\");}</STYLE>";
00204         $actualString = RemoveXSS::process($testString);
00205 
00206         $this->assertEquals($expectedString, $actualString);
00207     }
00208     /**
00209      * @test
00210      */
00211     public function checkAttackImageVbscript() {
00212         $testString = "<IMG SRC='vbscript:msgbox(\"XSS\")'>";
00213         $expectedString = "<IMG SRC='vb<x>script:msgbox(\"XSS\")'>";
00214         $actualString = RemoveXSS::process($testString);
00215 
00216         $this->assertEquals($expectedString, $actualString);
00217     }
00218     /**
00219      * @test
00220      */
00221     public function checkAttackLayer() {
00222         $testString = "<LAYER SRC=\"http://ha.ckers.org/scriptlet.html\"></LAYER>";
00223         $expectedString = "<la<x>yer SRC=\"http://ha.ckers.org/scriptlet.html\"></LAYER>";
00224         $actualString = RemoveXSS::process($testString);
00225 
00226         $this->assertEquals($expectedString, $actualString);
00227     }
00228     /**
00229      * @test
00230      */
00231     public function checkAttackMeta() {
00232         $testString = '<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert(\'XSS\');">';
00233         $expectedString = '<me<x>ta HTTP-EQUIV="refresh" CONTENT="0;url=ja<x>vascript:alert(\'XSS\');">';
00234         $actualString = RemoveXSS::process($testString);
00235 
00236         $this->assertEquals($expectedString, $actualString);
00237     }
00238     /**
00239      * @test
00240      */
00241     public function checkAttackMetaWithUrl() {
00242         $testString = '<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">';
00243         $expectedString = '<me<x>ta HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">';
00244         $actualString = RemoveXSS::process($testString);
00245 
00246         $this->assertEquals($expectedString, $actualString);
00247     }
00248     /**
00249      * @test
00250      */
00251     public function checkAttackMetaWithUrlExtended() {
00252         $testString = '<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert(\'XSS\');">';
00253         $expectedString = '<me<x>ta HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=ja<x>vascript:alert(\'XSS\');">';
00254         $actualString = RemoveXSS::process($testString);
00255 
00256         $this->assertEquals($expectedString, $actualString);
00257     }
00258     /**
00259      * @test
00260      */
00261     public function checkAttackObject() {
00262         $testString = '<OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>';
00263         $expectedString = '<ob<x>ject TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>';
00264         $actualString = RemoveXSS::process($testString);
00265 
00266         $this->assertEquals($expectedString, $actualString);
00267     }
00268     /**
00269      * @test
00270      */
00271     public function checkAttackObjectEmbeddedXss() {
00272         $testString = '<OBJECT classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=javascript:alert(\'XSS\')></OBJECT>';
00273         $expectedString = '<ob<x>ject classid=clsid:ae24fdae-03c6-11d1-8b76-0080c744f389><param name=url value=ja<x>vascript:alert(\'XSS\')></OBJECT>';
00274         $actualString = RemoveXSS::process($testString);
00275 
00276         $this->assertEquals($expectedString, $actualString);
00277     }
00278     /**
00279      * @test
00280      */
00281     public function checkAttackEmbedFlash() {
00282         $testString = '<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>';
00283         $expectedString = '<em<x>bed SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>';
00284         $actualString = RemoveXSS::process($testString);
00285 
00286         $this->assertEquals($expectedString, $actualString);
00287     }
00288     /**
00289      * @test
00290      */
00291     public function checkAttackActionScriptEval() {
00292         $testString = 'a="get";b="URL("";c="javascript:";d="alert(\'XSS\');")";eval(a+b+c+d);";';
00293         $expectedString = 'a="get";b="URL("";c="ja<x>vascript:";d="alert(\'XSS\');")";eval(a+b+c+d);";';
00294         $actualString = RemoveXSS::process($testString);
00295 
00296         $this->assertEquals($expectedString, $actualString);
00297     }
00298     /**
00299      * @test
00300      */
00301     public function checkAttackImageStyleWithComment() {
00302         $testString = '<IMG STYLE="xss:expr/*XSS*/ession(alert(\'XSS\'))">';
00303         $expectedString = '<IMG st<x>yle="xss:expr/*XSS*/ession(alert(\'XSS\'))">';
00304         $actualString = RemoveXSS::process($testString);
00305 
00306         $this->assertEquals($expectedString, $actualString);
00307     }
00308     /**
00309      * @test
00310      */
00311     public function checkAttackStyleInAnonymousHtml() {
00312         $testString = '<XSS STYLE="xss:expression(alert(\'XSS\'))">';
00313         $expectedString = '<XSS st<x>yle="xss:expression(alert(\'XSS\'))">';
00314         $actualString = RemoveXSS::process($testString);
00315 
00316         $this->assertEquals($expectedString, $actualString);
00317     }
00318     /**
00319      * @test
00320      */
00321     public function checkAttackStyleWithBackgroundImage() {
00322         $testString = '<STYLE>.XSS{background-image:url("javascript:alert(\'XSS\')");}</STYLE><A CLASS=XSS></A>';
00323         $expectedString = '<st<x>yle>.XSS{background-image:url("ja<x>vascript:alert(\'XSS\')");}</STYLE><A CLASS=XSS></A>';
00324         $actualString = RemoveXSS::process($testString);
00325 
00326         $this->assertEquals($expectedString, $actualString);
00327     }
00328     /**
00329      * @test
00330      */
00331     public function checkAttackStyleWithBackground() {
00332         $testString = '<STYLE type="text/css">BODY{background:url("javascript:alert(\'XSS\')")}</STYLE>';
00333         $expectedString = '<st<x>yle type="text/css">BODY{background:url("ja<x>vascript:alert(\'XSS\')")}</STYLE>';
00334         $actualString = RemoveXSS::process($testString);
00335 
00336         $this->assertEquals($expectedString, $actualString);
00337     }
00338     /**
00339      * @test
00340      */
00341     public function checkAttackStylesheet() {
00342         $testString = '<LINK REL="stylesheet" HREF="javascript:alert(\'XSS\');">';
00343         $expectedString = '<li<x>nk REL="stylesheet" HREF="ja<x>vascript:alert(\'XSS\');">';
00344         $actualString = RemoveXSS::process($testString);
00345 
00346         $this->assertEquals($expectedString, $actualString);
00347     }
00348     /**
00349      * @test
00350      */
00351     public function checkAttackRemoteStylesheet() {
00352         $testString = '<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">';
00353         $expectedString = '<li<x>nk REL="stylesheet" HREF="http://ha.ckers.org/xss.css">';
00354         $actualString = RemoveXSS::process($testString);
00355 
00356         $this->assertEquals($expectedString, $actualString);
00357     }
00358     /**
00359      * @test
00360      */
00361     public function checkAttackImportRemoteStylesheet() {
00362         $testString = '<STYLE>@import\'http://ha.ckers.org/xss.css\';</STYLE>';
00363         $expectedString = '<st<x>yle>@import\'http://ha.ckers.org/xss.css\';</STYLE>';
00364         $actualString = RemoveXSS::process($testString);
00365 
00366         $this->assertEquals($expectedString, $actualString);
00367     }
00368 
00369     /**
00370      * @return array<array> input strings and expected output strings to test
00371      *
00372      * @see processWithDataProvider
00373      */
00374     public function processDataProvider() {
00375         return array(
00376             'attackWithHexEncodedCharacter' => array(
00377                 '<a href="j&#x61;vascript:alert(123);">click</a>',
00378                 '<a href="ja<x>vascript:alert(123);">click</a>',
00379             ),
00380             'attackWithNestedHexEncodedCharacter' => array(
00381                 '<a href="j&#x6&#x31;;vascript:alert(123);">click</a>',
00382                 '<a href="ja<x>vascript:alert(123);">click</a>',
00383             ),
00384             'attackWithUnicodeNumericalEncodedCharacter' => array(
00385                 '<a href="j&#x6&#x31;;vascript:alert(123);">click</a>',
00386                 '<a href="ja<x>vascript:alert(123);">click</a>',
00387             ),
00388             'attackWithNestedUnicodeNumericalEncodedCharacter' => array(
00389                 '<a href="j&#6&#53;;vascript:alert(123);">click</a>',
00390                 '<a href="ja<x>vascript:alert(123);">click</a>',
00391             ),
00392         );
00393     }
00394 
00395     /**
00396      * @test
00397      *
00398      * @param string $input input value to test
00399      * @param string $expected expected output value
00400      *
00401      * @dataProvider processDataProvider
00402      */
00403     public function processWithDataProvider($input, $expected) {
00404         $this->assertEquals(
00405             $expected,
00406             RemoveXSS::process($input)
00407         );
00408     }
00409 }
00410 ?>