PHP Classes
elePHPant
Icontem

File: test_xss_attacks.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Manuel Lemos  >  Secure HTML parser and filter  >  test_xss_attacks.php  >  Download  
File: test_xss_attacks.php
Role: Unit test script
Content type: text/plain
Description: Script that tests the results of the safe HTML filter class against the XSS attack vectors from ha.ckers.org
Class: Secure HTML parser and filter
Parse and filter insecure HTML tags and CSS styles
Author: By
Last change:
Date: 5 years ago
Size: 6,124 bytes
 

Contents

Class file image Download
<?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";
?>