PHP Classes

File: class.inputfilter_clean.php

Recommend this page to a friend!
  Classes of Daniel Morris   PHP Input Filter   class.inputfilter_clean.php   Download  
File: class.inputfilter_clean.php
Role: Class source
Content type: text/plain
Description: PHP4/PHP5 without comments
Class: PHP Input Filter
Filter out unwanted PHP / Javascript / HTML tags.
Author: By
Last change: Changes:
4 Patches added. (Including new SQL injection feature)
1 Requested feature added.
2 Bugfixes.
Date: 18 years ago
Size: 7,607 bytes
 

Contents

Class file image Download
<?php
/** @class: InputFilter (PHP4 & PHP5, without comments)
  * @project: PHP Input Filter
  * @date: 10-05-2005
  * @version: 1.2.2_php4/php5
  * @author: Daniel Morris
  * @contributors: Gianpaolo Racca, Ghislain Picard, Marco Wandschneider, Chris Tobin and Andrew Eddie.
  * @copyright: Daniel Morris
  * @email: dan@rootcube.com
  * @license: GNU General Public License (GPL)
  */
class InputFilter {
    var
$tagsArray;
    var
$attrArray;
    var
$tagsMethod;
    var
$attrMethod;
    var
$xssAuto;
    var
$tagBlacklist = array('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml');
    var
$attrBlacklist = array('action', 'background', 'codebase', 'dynsrc', 'lowsrc');
    function
inputFilter($tagsArray = array(), $attrArray = array(), $tagsMethod = 0, $attrMethod = 0, $xssAuto = 1) {
        for (
$i = 0; $i < count($tagsArray); $i++) $tagsArray[$i] = strtolower($tagsArray[$i]);
        for (
$i = 0; $i < count($attrArray); $i++) $attrArray[$i] = strtolower($attrArray[$i]);
       
$this->tagsArray = (array) $tagsArray;
       
$this->attrArray = (array) $attrArray;
       
$this->tagsMethod = $tagsMethod;
       
$this->attrMethod = $attrMethod;
       
$this->xssAuto = $xssAuto;
    }
    function
process($source) {
        if (
is_array($source)) {
            foreach(
$source as $key => $value)
                if (
is_string($value)) $source[$key] = $this->remove($this->decode($value));
            return
$source;
        } else if (
is_string($source)) {
            return
$this->remove($this->decode($source));
        } else return
$source;
    }
    function
remove($source) {
       
$loopCounter=0;
        while(
$source != $this->filterTags($source)) {
           
$source = $this->filterTags($source);
           
$loopCounter++;
        }
        return
$source;
    }
    function
filterTags($source) {
       
$preTag = NULL;
       
$postTag = $source;
       
$tagOpen_start = strpos($source, '<');
        while(
$tagOpen_start !== FALSE) {
           
$preTag .= substr($postTag, 0, $tagOpen_start);
           
$postTag = substr($postTag, $tagOpen_start);
           
$fromTagOpen = substr($postTag, 1);
           
$tagOpen_end = strpos($fromTagOpen, '>');
            if (
$tagOpen_end === false) break;
           
$tagOpen_nested = strpos($fromTagOpen, '<');
            if ((
$tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end)) {
               
$preTag .= substr($postTag, 0, ($tagOpen_nested+1));
               
$postTag = substr($postTag, ($tagOpen_nested+1));
               
$tagOpen_start = strpos($postTag, '<');
                continue;
            }
           
$tagOpen_nested = (strpos($fromTagOpen, '<') + $tagOpen_start + 1);
           
$currentTag = substr($fromTagOpen, 0, $tagOpen_end);
           
$tagLength = strlen($currentTag);
            if (!
$tagOpen_end) {
               
$preTag .= $postTag;
               
$tagOpen_start = strpos($postTag, '<');
            }
           
$tagLeft = $currentTag;
           
$attrSet = array();
           
$currentSpace = strpos($tagLeft, ' ');
            if (
substr($currentTag, 0, 1) == "/") {
               
$isCloseTag = TRUE;
                list(
$tagName) = explode(' ', $currentTag);
               
$tagName = substr($tagName, 1);
            } else {
               
$isCloseTag = FALSE;
                list(
$tagName) = explode(' ', $currentTag);
            }
            if ((!
preg_match("/^[a-z][a-z0-9]*$/i",$tagName)) || (!$tagName) || ((in_array(strtolower($tagName), $this->tagBlacklist)) && ($this->xssAuto))) {
               
$postTag = substr($postTag, ($tagLength + 2));
               
$tagOpen_start = strpos($postTag, '<');
                continue;
            }
            while (
$currentSpace !== FALSE) {
               
$fromSpace = substr($tagLeft, ($currentSpace+1));
               
$nextSpace = strpos($fromSpace, ' ');
               
$openQuotes = strpos($fromSpace, '"');
               
$closeQuotes = strpos(substr($fromSpace, ($openQuotes+1)), '"') + $openQuotes + 1;
                if (
strpos($fromSpace, '=') !== FALSE) {
                    if ((
$openQuotes !== FALSE) && (strpos(substr($fromSpace, ($openQuotes+1)), '"') !== FALSE))
                       
$attr = substr($fromSpace, 0, ($closeQuotes+1));
                    else
$attr = substr($fromSpace, 0, $nextSpace);
                } else
$attr = substr($fromSpace, 0, $nextSpace);
                if (!
$attr) $attr = $fromSpace;
               
$attrSet[] = $attr;
               
$tagLeft = substr($fromSpace, strlen($attr));
               
$currentSpace = strpos($tagLeft, ' ');
            }
           
$tagFound = in_array(strtolower($tagName), $this->tagsArray);
            if ((!
$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod)) {
                if (!
$isCloseTag) {
                   
$attrSet = $this->filterAttr($attrSet);
                   
$preTag .= '<' . $tagName;
                    for (
$i = 0; $i < count($attrSet); $i++)
                       
$preTag .= ' ' . $attrSet[$i];
                    if (
strpos($fromTagOpen, "</" . $tagName)) $preTag .= '>';
                    else
$preTag .= ' />';
                } else
$preTag .= '</' . $tagName . '>';
            }
           
$postTag = substr($postTag, ($tagLength + 2));
           
$tagOpen_start = strpos($postTag, '<');
        }
       
$preTag .= $postTag;
        return
$preTag;
    }
    function
filterAttr($attrSet) {
       
$newSet = array();
        for (
$i = 0; $i <count($attrSet); $i++) {
            if (!
$attrSet[$i]) continue;
           
$attrSubSet = explode('=', trim($attrSet[$i]));
            list(
$attrSubSet[0]) = explode(' ', $attrSubSet[0]);
            if ((!
eregi("^[a-z]*$",$attrSubSet[0])) || (($this->xssAuto) && ((in_array(strtolower($attrSubSet[0]), $this->attrBlacklist)) || (substr($attrSubSet[0], 0, 2) == 'on'))))
                continue;
            if (
$attrSubSet[1]) {
               
$attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]);
               
$attrSubSet[1] = preg_replace('/\s+/', '', $attrSubSet[1]);
               
$attrSubSet[1] = str_replace('"', '', $attrSubSet[1]);
                if ((
substr($attrSubSet[1], 0, 1) == "'") && (substr($attrSubSet[1], (strlen($attrSubSet[1]) - 1), 1) == "'"))
                   
$attrSubSet[1] = substr($attrSubSet[1], 1, (strlen($attrSubSet[1]) - 2));
               
$attrSubSet[1] = stripslashes($attrSubSet[1]);
            }
            if ( ((
strpos(strtolower($attrSubSet[1]), 'expression') !== false) && (strtolower($attrSubSet[0]) == 'style')) ||
                    (
strpos(strtolower($attrSubSet[1]), 'javascript:') !== false) ||
                    (
strpos(strtolower($attrSubSet[1]), 'behaviour:') !== false) ||
                    (
strpos(strtolower($attrSubSet[1]), 'vbscript:') !== false) ||
                    (
strpos(strtolower($attrSubSet[1]), 'mocha:') !== false) ||
                    (
strpos(strtolower($attrSubSet[1]), 'livescript:') !== false)
            ) continue;
           
$attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
            if ((!
$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) {
                if (
$attrSubSet[1]) $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"';
                else if (
$attrSubSet[1] == "0") $newSet[] = $attrSubSet[0] . '="0"';
                else
$newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"';
            }
        }
        return
$newSet;
    }
    function
decode($source) {
       
$source = html_entity_decode($source, ENT_QUOTES, "ISO-8859-1");
       
$source = preg_replace('/&#(\d+);/me',"chr(\\1)", $source);
       
$source = preg_replace('/&#x([a-f0-9]+);/mei',"chr(0x\\1)", $source);
        return
$source;
    }
    function
safeSQL($source, &$connection) {
        if (
is_array($source)) {
            foreach(
$source as $key => $value)
                if (
is_string($value)) $source[$key] = $this->quoteSmart($this->decode($value), $connection);
            return
$source;
        } else if (
is_string($source)) {
            if (
is_string($source)) return $this->quoteSmart($this->decode($source), $connection);
        } else return
$source;
    }
    function
quoteSmart($source, &$connection) {
        if (
get_magic_quotes_gpc()) $source = stripslashes($source);
       
$source = $this->escapeString($source, $connection);
        return
$source;
    }
    function
escapeString($string, &$connection) {
        if (
version_compare(phpversion(),"4.3.0", "<")) mysql_escape_string($string);
        else
mysql_real_escape_string($string);
        return
$string;
    }
}
?>