Changeset 245 for trunk/trax/vendor/trax

Show
Ignore:
Timestamp:
08/23/06 00:15:06 (6 years ago)
Author:
john
Message:

made it so input filter can specify field exceptions not to check

Location:
trunk/trax/vendor/trax
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/trax/vendor/trax/dispatcher.php

    r162 r245  
    6161    function dispatch() { 
    6262        try { 
    63             InputFilter::process_all(array(),array(),1,1); 
     63            InputFilter::process_all(); 
    6464            Session::start(); 
    6565            $ac = new ActionController(); 
  • trunk/trax/vendor/trax/input_filter.php

    r199 r245  
    3737     *  Whether the tags in this list are accepted or rejected is 
    3838     *  determined by the value of {@link $tagsMethod}. 
    39      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    4039     *  @var string[] 
    4140     */ 
    42     static protected $tagsArray = array();  // default = empty array 
     41    protected static $tagsArray = array();  // default = empty array 
    4342     
    4443    /** 
     
    4746     *  Whether the attributes in this list are accepted or rejected is 
    4847     *  determined by the value of {@link $attrMethod}. 
    49      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    5048     *  @var string[] 
    5149     */ 
    52     static protected $attrArray = array();  // default = empty array 
     50    protected static $attrArray = array();  // default = empty array 
    5351     
    5452    /** 
     
    6765     *                 {@link $tagsArray}.</li>  
    6866     *  </ul> 
    69      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    70      */ 
    71     static protected $tagsMethod = 0;   // default = 0 
     67     */ 
     68    protected static $tagsMethod = true; 
    7269     
    7370    /** 
     
    8683     *                 {@link $attrArray}.</li>  
    8784     *  </ul> 
    88      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    89      */ 
    90     static protected $attrMethod = 0;   // default = 0 
     85     */ 
     86    protected static $attrMethod = true; 
    9187 
    9288     
     
    106102     *      {@link $attrBlacklist}.</li>  
    107103     *  </ul> 
    108      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    109      */ 
    110     static protected $xssAuto = 1;     // default = 1 
     104     */ 
     105    protected static $xssAuto = true; 
     106 
     107    /** 
     108     *  Fields to ignore that you want html and other banned stuff in. 
     109     * 
     110     *  @var array 
     111     */  
     112    protected static $exception_fields = array(); 
    111113     
    112114    /** 
     
    115117     *  If {@link $xssAuto} is true, remove the tags in this list. 
    116118     *  @var string[] 
    117      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    118      */ 
    119     static protected $tagBlacklist = 
     119     */ 
     120    protected static $tagBlacklist = 
    120121        array('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 
    121122              'frame', 'frameset', 'head', 'html', 'id', 'iframe', 
     
    128129     *  If {@link $xssAuto} is true, remove the attributes in this list. 
    129130     *  @var string[] 
    130      *  <b>FIXME:</b> static declaration must be after visibility declaration 
    131      */ 
    132     static protected $attrBlacklist = 
     131     */ 
     132    protected static $attrBlacklist = 
    133133        array('action', 'background', 'codebase', 'dynsrc', 'lowsrc');  
    134134         
    135135    /**  
    136      *  Constructor for InputFilter class. 
     136     *  Initializer for InputFilter class. 
    137137     * 
    138138     *  @param string[] $tagsArray  User-provided list of tags to 
     
    172172     *  @uses $tagsMethod 
    173173     */ 
    174     public function __construct($tagsArray = array(), $attrArray = array(), 
    175                                 $tagsMethod = 0, $attrMethod = 0, 
    176                                 $xssAuto = 1) {  
     174    public function init($tagsArray = array(), $attrArray = array(), 
     175                                $tagsMethod = true, $attrMethod = true, 
     176                                $xssAuto = true) {  
     177                                     
    177178        // make sure user defined arrays are in lowercase 
    178179        for ($i = 0; $i < count($tagsArray); $i++) $tagsArray[$i] = strtolower($tagsArray[$i]); 
     
    185186        self::$xssAuto = $xssAuto; 
    186187    } 
     188 
     189    /** 
     190     *  Adds a field to exclude from filtering 
     191     * 
     192     */  
     193    public function add_field_exception($field) { 
     194        if($field) { 
     195            self::$exception_fields[] = $field;    
     196        } 
     197    } 
     198 
     199    /** 
     200     *  Clears all previous field exceptions 
     201     * 
     202     */      
     203    public function clear_field_exceptions() { 
     204        self::$exception_fields = array();         
     205    }  
    187206 
    188207    /** 
     
    233252     */ 
    234253    public function process_all($tagsArray = array(), $attrArray = array(), 
    235                                 $tagsMethod = 0, $attrMethod = 0, 
    236                                 $xssAuto = 1) { 
    237         self::__construct($tagsArray, $attrArray, $tagsMethod, 
     254                                $tagsMethod = true, $attrMethod = true, 
     255                                $xssAuto = true) { 
     256        self::init($tagsArray, $attrArray, $tagsMethod, 
    238257                          $attrMethod, $xssAuto); 
    239258        if(count($_POST)) { 
     
    258277     *  @uses remove() 
    259278     */ 
    260     public function process($source) { 
     279    public function process($source, $extra_key = null) { 
    261280        // clean all elements in this array 
    262         if (is_array($source)) { 
     281        if(is_array($source)) { 
    263282            foreach($source as $key => $value) { 
     283                //error_log("key:".$extra_key.$key); 
     284                if(in_array($extra_key.$key, self::$exception_fields)) { $source[$key] = $value; continue; } 
    264285                // for arrays in arrays 
    265                 if (is_array($value)) $source[$key] = self::process($value); 
     286                if (is_array($value)) $source[$key] = self::process($value, $key.":"); 
    266287                // filter element for XSS and other 'bad' code etc. 
    267288                if (is_string($value)) $source[$key] = self::remove(self::decode($value)); 
     
    269290            return $source; 
    270291        // clean this string 
    271         } else if (is_string($source)) { 
     292        } elseif(is_string($source)) { 
    272293            // filter source for XSS and other 'bad' code etc. 
    273294            return self::remove(self::decode($source)); 
    274295        // return parameter as given 
    275         } else return $source;   
     296        } else { 
     297            return $source;  
     298        } 
    276299    } 
    277300 
     
    286309     */ 
    287310    protected function remove($source) { 
    288         //  FIXME: what do we use $loopCounter for? 
    289         $loopCounter=0; 
    290311        // provides nested-tag protection 
    291312        while($source != self::filterTags($source)) { 
    292313            $source = self::filterTags($source); 
    293             $loopCounter++; 
    294314        } 
    295315        return $source; 
     
    318338    protected function filterTags($source) { 
    319339        // filter pass setup 
    320         $preTag = NULL; 
     340        $preTag = null; 
    321341        $postTag = $source; 
    322342        // find initial tag's position 
    323343        $tagOpen_start = strpos($source, '<'); 
    324344        // interate through string until no tags left 
    325         while($tagOpen_start !== FALSE) { 
     345        while($tagOpen_start !== false) { 
    326346            // process tag interatively 
    327347            $preTag .= substr($postTag, 0, $tagOpen_start); 
     
    352372            // is end tag 
    353373            if (substr($currentTag, 0, 1) == "/") { 
    354                 $isCloseTag = TRUE; 
     374                $isCloseTag = true; 
    355375                list($tagName) = explode(' ', $currentTag); 
    356376                $tagName = substr($tagName, 1); 
    357377            // is start tag 
    358378            } else { 
    359                 $isCloseTag = FALSE; 
     379                $isCloseTag = false; 
    360380                list($tagName) = explode(' ', $currentTag); 
    361381            }        
     
    368388            } 
    369389            // this while is needed to support attribute values with spaces in! 
    370             while ($currentSpace !== FALSE) { 
     390            while ($currentSpace !== false) { 
    371391                $fromSpace = substr($tagLeft, ($currentSpace+1)); 
    372392                $nextSpace = strpos($fromSpace, ' '); 
     
    374394                $closeQuotes = strpos(substr($fromSpace, ($openQuotes+1)), '"') + $openQuotes + 1; 
    375395                // another equals exists 
    376                 if (strpos($fromSpace, '=') !== FALSE) { 
     396                if (strpos($fromSpace, '=') !== false) { 
    377397                    // opening and closing quotes exists 
    378                     if (($openQuotes !== FALSE) && (strpos(substr($fromSpace, ($openQuotes+1)), '"') !== FALSE)) 
     398                    if (($openQuotes !== false) && (strpos(substr($fromSpace, ($openQuotes+1)), '"') !== false)) 
    379399                        $attr = substr($fromSpace, 0, ($closeQuotes+1)); 
    380400                    // one or neither exist 
     
    457477                continue; 
    458478            // xss attr value filtering 
    459             if ($attrSubSet[1]) { 
     479            if ($attrSubSet[1] || is_numeric($attrSubSet[1])) { 
    460480                // strips unicode, hex, etc 
    461481                $attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]); 
     
    471491            } 
    472492            // auto strip attr's with "javascript: 
    473             if (    ((strpos(strtolower($attrSubSet[1]), 'expression') !== false) &&    (strtolower($attrSubSet[0]) == 'style')) || 
    474                     (strpos(strtolower($attrSubSet[1]), 'javascript:') !== false) || 
    475                     (strpos(strtolower($attrSubSet[1]), 'behaviour:') !== false) || 
    476                     (strpos(strtolower($attrSubSet[1]), 'vbscript:') !== false) || 
    477                     (strpos(strtolower($attrSubSet[1]), 'mocha:') !== false) || 
    478                     (strpos(strtolower($attrSubSet[1]), 'livescript:') !== false)  
    479             ) continue; 
     493            if (((strpos(strtolower($attrSubSet[1]), 'expression') !== false) &&  
     494                (strtolower($attrSubSet[0]) == 'style')) || 
     495                (strpos(strtolower($attrSubSet[1]), 'javascript:') !== false) || 
     496                (strpos(strtolower($attrSubSet[1]), 'behaviour:') !== false) || 
     497                (strpos(strtolower($attrSubSet[1]), 'vbscript:') !== false) || 
     498                (strpos(strtolower($attrSubSet[1]), 'mocha:') !== false) || 
     499                (strpos(strtolower($attrSubSet[1]), 'livescript:') !== false)  
     500            ) { continue; } 
    480501 
    481502            // if matches user defined array 
    482503            $attrFound = in_array(strtolower($attrSubSet[0]), self::$attrArray); 
     504            //error_log("attrFound:".($attrFound ? "Yes" : "No")); 
    483505            // keep this attr on condition 
    484506            if ((!$attrFound && self::$attrMethod) || ($attrFound && !self::$attrMethod)) { 
     507                //error_log($attrSubSet[0]."=".$attrSubSet[1]); 
    485508                // attr has value 
    486                 if ($attrSubSet[1]) $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"'; 
     509                if($attrSubSet[1]) { 
     510                    $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"'; 
    487511                // attr has decimal zero as value 
    488                 else if ($attrSubSet[1] == "0") $newSet[] = $attrSubSet[0] . '="0"'; 
     512                } elseif ($attrSubSet[1] == "0") {  
     513                    $newSet[] = $attrSubSet[0] . '="0"'; 
    489514                // reformat single attributes to XHTML 
    490                 else $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"'; 
     515                } else { 
     516                    $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"'; 
     517                } 
    491518            }    
    492519        } 
     
    515542        return $source; 
    516543    } 
    517  
    518     /**  
    519      *  Remove HTML entities and magic quotes, insert SQL special 
    520      *  character escapes 
    521      * 
    522      *  If the input is a string or an array of strings, then each 
    523      *  string is edited to convert any HTML entities to the 
    524      *  corresponding character and remove slashes inserted by 
    525      *  {@link http://www.php.net/manual/en/security.magicquotes.php magic quotes}, 
    526      *  then the result has SQL special characters 
    527      *  escaped. 
    528      *  @param mixed $source Input to be 'cleaned' 
    529      *  @param resource $connection  An open MySQL connection 
    530      *  @return mixed $source with HTML entities and GPC magic quotes 
    531      *                removed from, and SQL special character escapes 
    532      *                inserted in, the string or array of strings. 
    533      *  @uses decode() 
    534      *  @uses quoteSmart() 
    535      */ 
    536     public function safeSQL($source, &$connection) { 
    537         // clean all elements in this array 
    538         if (is_array($source)) { 
    539             foreach($source as $key => $value) 
    540                 // filter element for SQL injection 
    541                 if (is_string($value)) $source[$key] = self::quoteSmart(self::decode($value), $connection); 
    542             return $source; 
    543         // clean this string 
    544         } else if (is_string($source)) { 
    545             // filter source for SQL injection 
    546             if (is_string($source)) return self::quoteSmart(self::decode($source), $connection); 
    547         // return parameter as given 
    548         } else return $source;   
    549     } 
    550  
    551     /**  
    552      *  Remove GPC magic quotes from input string & escape SQL special 
    553      *  characters 
    554      * 
    555      *  The input is a string that came from a GET or POST HTTP 
    556      *  operation, or a cookie.  If GPC magic quotes are currently in 
    557      *  effect, the resulting slashes are stripped.  Then any SQL 
    558      *  special characters in the string are escaped, taking into 
    559      *  account the character set in use on $connection. 
    560      *  @author Chris Tobin, Daniel Morris 
    561      *  @param string $source Input string to be converted 
    562      *  @param resource $connection An open MySQL connection 
    563      *  @return string Input string with any GPC magic quotes stripped 
    564      *                 and SQL special characters escaped 
    565      *  @uses escapeString() 
    566      *  @uses get_magic_quotes_gpc() 
    567      *  @uses stripslashes() 
    568      */ 
    569     protected function quoteSmart($source, &$connection) { 
    570         // strip slashes 
    571         if (get_magic_quotes_gpc()) $source = stripslashes($source); 
    572         // quote both numeric and text 
    573         $source = self::escapeString($source, $connection); 
    574         return $source; 
    575     } 
    576      
    577     /**  
    578      *  Escape SQL special characters in string 
    579      * 
    580      *  Escape SQL special characters in the input string, taking into 
    581      *  account the character set of the connection. 
    582      * 
    583      *  <b>FIXME:</b> since we require PHP 5 can't we remove the use 
    584      *  of mysql_esacape_string()? 
    585      * 
    586      *  <b>FIXME:</b>Shouldn't we pass the connection to 
    587      *  mysql_real_escape_string()?  
    588      * 
    589      *  <b>FIXME:</b>Is this really RDBMS independent? 
    590      *  @todo Check FIXMEs 
    591      *  @author Chris Tobin, Daniel Morris 
    592      *  @param string $string  String to be protected 
    593      *  @param resource $connection - An open MySQL connection 
    594      *  @return string Value of $string with characters special in 
    595      *                 SQL escaped by '\'s 
    596      *  @uses mysql_escape_string() 
    597      *  @uses mysql_real_escape_string() 
    598      *  @uses phpversion() 
    599      *  @uses version_compare() 
    600      */  
    601     protected function escapeString($string, &$connection) { 
    602         // depreciated function 
    603         if (version_compare(phpversion(),"4.3.0", "<")) 
    604             return mysql_escape_string($string); 
    605         // current function 
    606         else 
    607             return mysql_real_escape_string($string); 
    608     } 
    609544} 
    610545