Changeset 245 for trunk/trax/vendor/trax/input_filter.php
- Timestamp:
- 08/23/06 00:15:06 (6 years ago)
- Files:
-
- 1 modified
-
trunk/trax/vendor/trax/input_filter.php (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/trax/vendor/trax/input_filter.php
r199 r245 37 37 * Whether the tags in this list are accepted or rejected is 38 38 * determined by the value of {@link $tagsMethod}. 39 * <b>FIXME:</b> static declaration must be after visibility declaration40 39 * @var string[] 41 40 */ 42 static protected$tagsArray = array(); // default = empty array41 protected static $tagsArray = array(); // default = empty array 43 42 44 43 /** … … 47 46 * Whether the attributes in this list are accepted or rejected is 48 47 * determined by the value of {@link $attrMethod}. 49 * <b>FIXME:</b> static declaration must be after visibility declaration50 48 * @var string[] 51 49 */ 52 static protected$attrArray = array(); // default = empty array50 protected static $attrArray = array(); // default = empty array 53 51 54 52 /** … … 67 65 * {@link $tagsArray}.</li> 68 66 * </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; 72 69 73 70 /** … … 86 83 * {@link $attrArray}.</li> 87 84 * </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; 91 87 92 88 … … 106 102 * {@link $attrBlacklist}.</li> 107 103 * </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(); 111 113 112 114 /** … … 115 117 * If {@link $xssAuto} is true, remove the tags in this list. 116 118 * @var string[] 117 * <b>FIXME:</b> static declaration must be after visibility declaration 118 */ 119 static protected $tagBlacklist = 119 */ 120 protected static $tagBlacklist = 120 121 array('applet', 'body', 'bgsound', 'base', 'basefont', 'embed', 121 122 'frame', 'frameset', 'head', 'html', 'id', 'iframe', … … 128 129 * If {@link $xssAuto} is true, remove the attributes in this list. 129 130 * @var string[] 130 * <b>FIXME:</b> static declaration must be after visibility declaration 131 */ 132 static protected $attrBlacklist = 131 */ 132 protected static $attrBlacklist = 133 133 array('action', 'background', 'codebase', 'dynsrc', 'lowsrc'); 134 134 135 135 /** 136 * Constructor for InputFilter class.136 * Initializer for InputFilter class. 137 137 * 138 138 * @param string[] $tagsArray User-provided list of tags to … … 172 172 * @uses $tagsMethod 173 173 */ 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 177 178 // make sure user defined arrays are in lowercase 178 179 for ($i = 0; $i < count($tagsArray); $i++) $tagsArray[$i] = strtolower($tagsArray[$i]); … … 185 186 self::$xssAuto = $xssAuto; 186 187 } 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 } 187 206 188 207 /** … … 233 252 */ 234 253 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, 238 257 $attrMethod, $xssAuto); 239 258 if(count($_POST)) { … … 258 277 * @uses remove() 259 278 */ 260 public function process($source ) {279 public function process($source, $extra_key = null) { 261 280 // clean all elements in this array 262 if (is_array($source)) {281 if(is_array($source)) { 263 282 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; } 264 285 // 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.":"); 266 287 // filter element for XSS and other 'bad' code etc. 267 288 if (is_string($value)) $source[$key] = self::remove(self::decode($value)); … … 269 290 return $source; 270 291 // clean this string 271 } else if(is_string($source)) {292 } elseif(is_string($source)) { 272 293 // filter source for XSS and other 'bad' code etc. 273 294 return self::remove(self::decode($source)); 274 295 // return parameter as given 275 } else return $source; 296 } else { 297 return $source; 298 } 276 299 } 277 300 … … 286 309 */ 287 310 protected function remove($source) { 288 // FIXME: what do we use $loopCounter for?289 $loopCounter=0;290 311 // provides nested-tag protection 291 312 while($source != self::filterTags($source)) { 292 313 $source = self::filterTags($source); 293 $loopCounter++;294 314 } 295 315 return $source; … … 318 338 protected function filterTags($source) { 319 339 // filter pass setup 320 $preTag = NULL;340 $preTag = null; 321 341 $postTag = $source; 322 342 // find initial tag's position 323 343 $tagOpen_start = strpos($source, '<'); 324 344 // interate through string until no tags left 325 while($tagOpen_start !== FALSE) {345 while($tagOpen_start !== false) { 326 346 // process tag interatively 327 347 $preTag .= substr($postTag, 0, $tagOpen_start); … … 352 372 // is end tag 353 373 if (substr($currentTag, 0, 1) == "/") { 354 $isCloseTag = TRUE;374 $isCloseTag = true; 355 375 list($tagName) = explode(' ', $currentTag); 356 376 $tagName = substr($tagName, 1); 357 377 // is start tag 358 378 } else { 359 $isCloseTag = FALSE;379 $isCloseTag = false; 360 380 list($tagName) = explode(' ', $currentTag); 361 381 } … … 368 388 } 369 389 // this while is needed to support attribute values with spaces in! 370 while ($currentSpace !== FALSE) {390 while ($currentSpace !== false) { 371 391 $fromSpace = substr($tagLeft, ($currentSpace+1)); 372 392 $nextSpace = strpos($fromSpace, ' '); … … 374 394 $closeQuotes = strpos(substr($fromSpace, ($openQuotes+1)), '"') + $openQuotes + 1; 375 395 // another equals exists 376 if (strpos($fromSpace, '=') !== FALSE) {396 if (strpos($fromSpace, '=') !== false) { 377 397 // 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)) 379 399 $attr = substr($fromSpace, 0, ($closeQuotes+1)); 380 400 // one or neither exist … … 457 477 continue; 458 478 // xss attr value filtering 459 if ($attrSubSet[1] ) {479 if ($attrSubSet[1] || is_numeric($attrSubSet[1])) { 460 480 // strips unicode, hex, etc 461 481 $attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]); … … 471 491 } 472 492 // 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; } 480 501 481 502 // if matches user defined array 482 503 $attrFound = in_array(strtolower($attrSubSet[0]), self::$attrArray); 504 //error_log("attrFound:".($attrFound ? "Yes" : "No")); 483 505 // keep this attr on condition 484 506 if ((!$attrFound && self::$attrMethod) || ($attrFound && !self::$attrMethod)) { 507 //error_log($attrSubSet[0]."=".$attrSubSet[1]); 485 508 // attr has value 486 if ($attrSubSet[1]) $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"'; 509 if($attrSubSet[1]) { 510 $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"'; 487 511 // 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"'; 489 514 // reformat single attributes to XHTML 490 else $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"'; 515 } else { 516 $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"'; 517 } 491 518 } 492 519 } … … 515 542 return $source; 516 543 } 517 518 /**519 * Remove HTML entities and magic quotes, insert SQL special520 * character escapes521 *522 * If the input is a string or an array of strings, then each523 * string is edited to convert any HTML entities to the524 * corresponding character and remove slashes inserted by525 * {@link http://www.php.net/manual/en/security.magicquotes.php magic quotes},526 * then the result has SQL special characters527 * escaped.528 * @param mixed $source Input to be 'cleaned'529 * @param resource $connection An open MySQL connection530 * @return mixed $source with HTML entities and GPC magic quotes531 * removed from, and SQL special character escapes532 * 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 array538 if (is_array($source)) {539 foreach($source as $key => $value)540 // filter element for SQL injection541 if (is_string($value)) $source[$key] = self::quoteSmart(self::decode($value), $connection);542 return $source;543 // clean this string544 } else if (is_string($source)) {545 // filter source for SQL injection546 if (is_string($source)) return self::quoteSmart(self::decode($source), $connection);547 // return parameter as given548 } else return $source;549 }550 551 /**552 * Remove GPC magic quotes from input string & escape SQL special553 * characters554 *555 * The input is a string that came from a GET or POST HTTP556 * operation, or a cookie. If GPC magic quotes are currently in557 * effect, the resulting slashes are stripped. Then any SQL558 * special characters in the string are escaped, taking into559 * account the character set in use on $connection.560 * @author Chris Tobin, Daniel Morris561 * @param string $source Input string to be converted562 * @param resource $connection An open MySQL connection563 * @return string Input string with any GPC magic quotes stripped564 * and SQL special characters escaped565 * @uses escapeString()566 * @uses get_magic_quotes_gpc()567 * @uses stripslashes()568 */569 protected function quoteSmart($source, &$connection) {570 // strip slashes571 if (get_magic_quotes_gpc()) $source = stripslashes($source);572 // quote both numeric and text573 $source = self::escapeString($source, $connection);574 return $source;575 }576 577 /**578 * Escape SQL special characters in string579 *580 * Escape SQL special characters in the input string, taking into581 * account the character set of the connection.582 *583 * <b>FIXME:</b> since we require PHP 5 can't we remove the use584 * of mysql_esacape_string()?585 *586 * <b>FIXME:</b>Shouldn't we pass the connection to587 * mysql_real_escape_string()?588 *589 * <b>FIXME:</b>Is this really RDBMS independent?590 * @todo Check FIXMEs591 * @author Chris Tobin, Daniel Morris592 * @param string $string String to be protected593 * @param resource $connection - An open MySQL connection594 * @return string Value of $string with characters special in595 * SQL escaped by '\'s596 * @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 function603 if (version_compare(phpversion(),"4.3.0", "<"))604 return mysql_escape_string($string);605 // current function606 else607 return mysql_real_escape_string($string);608 }609 544 } 610 545
