<?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"; ?>
|