<?php
/*
* test_xss_attacks.php
*
* @(#) $Header: /home/mlemos/cvsroot/markupparser/test_xss_attacks.php,v 1.12 2009/08/17 07:30:00 mlemos Exp $
*
*/
require_once('xml_parser.php');
require_once('markup_parser.php');
require_once('css_parser.php');
require_once('dtd_parser.php');
require_once('filecacheclass.php');
require_once('markup_filter_validator.php');
require_once('markup_filter_safe_html.php');
require_once('test/expect/attacks.php');
/*
* Get the latest XSS attacks definition file from:
* http://ha.ckers.org/xssAttacks.xml
*/
$xss_attacks_file = 'test/sample/xssAttacks.xml';
$tests = array();
if(IsSet($_SERVER['argv'])
&& GetType($_SERVER['argv']) == 'array'
&& count($_SERVER['argv']) > 1)
{
for($t = 1; $t < count($_SERVER['argv']); ++$t)
$tests[$_SERVER['argv'][$t]] = 1;
}
$filter = new markup_filter_safe_html_class;
$filter->track_lines = 1;
$errors = $passed = $failed = $unexpected = $skipped = 0;
$xml = new xml_parser_class;
$xml->store_positions = 1;
if(strlen($error = $xml->ParseFile($xss_attacks_file)) == 0)
{
$p = '0';
if(!strcmp($xml->structure[$p]['Tag'], 'xss'))
{
$te = $xml->structure[$p]['Elements'];
for($e = 0; $e < $te; ++$e)
{
$ep = $p.','.$e;
if(GetType($xml->structure[$ep]) == 'array')
{
switch($xml->structure[$ep]['Tag'])
{
case 'attack':
$attack = array();
$tee = $xml->structure[$ep]['Elements'];
for($ee = 0; $ee < $tee; ++$ee)
{
$eep = $ep.','.$ee;
if(GetType($xml->structure[$eep]) == 'array')
{
switch($property = $xml->structure[$eep]['Tag'])
{
case 'name':
case 'code':
case 'desc':
case 'label':
case 'browser':
$value = '';
$teee = $xml->structure[$eep]['Elements'];
for($eee = 0; $eee < $teee; ++$eee)
{
$eeep = $eep.','.$eee;
if(GetType($xml->structure[$eeep]) == 'array')
{
echo 'Error: ', $xml->structure[$eeep]['Tag'], ' is not a valid attack definition property value',"\n";
break 5;
}
else
$value .= $xml->structure[$eeep];
}
$attack[$property] = $value;
break;
default:
echo 'Error: ', $xml->structure[$eep]['Tag'], ' is not a valid attack definition property',"\n";
break 4;
}
}
elseif(strlen($error = $xml->VerifyWhiteSpace($eep)))
{
echo 'Error: ',$error,"\n";
break 3;
}
}
if(!IsSet($attack[$property = 'name'])
|| !IsSet($attack[$property = 'code']))
{
echo 'Error: attack property ', $property, ' is missing',"\n";
break 2;
}
$name = $attack['name'];
$code = $attack['code'];
if(IsSet($attacks[$name]['Decode'])
&& $attacks[$name]['Decode'])
$code = UrlDecode($code);
if(count($tests)
&& !IsSet($tests[$name]))
{
++$skipped;
break;
}
echo $name, ' ... ';
flush();
if((IsSet($attacks[$name]['Skip'])
&& $attacks[$name]['Skip']))
{
echo 'SKIPPED', "\n\n";
++$skipped;
break;
}
$parameters=array(
'Data'=>$code,
'OnlyBody'=>1,
'DTDCachePath'=>'',
);
if(($success = $filter->StartParsing($parameters)))
{
$filtered = '';
do
{
if(!($success = $filter->Parse($end, $elements)))
break;
$th = count($elements);
for($h = 0; $h < $th; ++$h)
{
if(!($success = $filter->RewriteElement($elements[$h], $html)))
break;
$filtered .= $html;
}
}
while(!$end);
if($success)
$success = $filter->FinishParsing();
}
if(!$success)
{
echo 'ERROR', "\n", $filter->error.' at position '.$filter->error_position;
if($filter->track_lines
&& $filter->GetPositionLine($filter->error_position, $line, $column))
echo ' line '.$line.' column '.$column;
echo "\n", 'Attack: ', $code, "\n";
++$errors;
}
elseif(!IsSet($attacks[$name]))
{
echo 'UNEXPECTED', "\n", 'Attack: ', $code, "\n", 'Filtered: ', $filtered, "\n";
++$unexpected;
}
elseif(strcasecmp($filtered = count($filter->warnings) ? $filtered : $code, $attacks[$name]['Filtered']))
{
echo 'FAIL', "\n", 'Attack: ', $code, "\n", 'Expected: ', $attacks[$name]['Filtered'], "\n", 'Filtered: ', $filtered, "\n";
++$failed;
}
else
{
echo 'PASS', "\n", 'Attack: ', $code, "\n";
++$passed;
}
for($warning = 0, Reset($filter->warnings); $warning < count($filter->warnings); Next($filter->warnings), $warning++)
{
$w = Key($filter->warnings);
echo 'Warning: ', $filter->warnings[$w], ' at position ', $w;
if($filter->track_lines
&& $filter->GetPositionLine($w, $line, $column))
echo ' line '.$line.' column '.$column;
echo "\n";
}
echo "\n";
break;
default:
echo 'Error: ', $xml->structure[$ep]['Tag'], ' is not a valid attack definition',"\n";
break 2;
}
}
elseif(strlen($error = $xml->VerifyWhiteSpace($ep)))
{
echo 'Error: ',$error,"\n";
break;
}
}
echo 'Total: ', (($performed = $passed + $failed + $unexpected + $errors) + $skipped);
if($passed)
echo ', Passed: ', $passed;
if($failed)
echo ', Failed: ', $failed;
if($unexpected)
echo ', Unexpected: ', $unexpected;
if($errors)
echo ', Errors: ', $errors;
if($skipped)
echo ', Skipped: ', $skipped;
if($performed)
echo ', Success: ', number_format(100*$passed/$performed, 1), '%';
echo "\n";
}
else
echo 'Error: ', $xss_attacks_file, 'is not a XSS attacks definition file',"\n";
}
else
echo 'Error: ', $error,"\n";
?>
|