From 3212f8cba5a1e6bdb0226ff071bcb670dd8d718a Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Wed, 16 Aug 2006 18:47:17 +0000 Subject: [PATCH] Moving input stuff out of the kernel and into Input --- Input.php | 423 +++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel.php | 369 ---------------------------------------------- 2 files changed, 423 insertions(+), 369 deletions(-) create mode 100644 Input.php diff --git a/Input.php b/Input.php new file mode 100644 index 0000000..391a970 --- /dev/null +++ b/Input.php @@ -0,0 +1,423 @@ +escape_binary() without cleaning - used in API +*/ +define('TYPE_BIN', 128); +/**#@-*/ + +/** +* Input Sanitizer +* +* This class is responsible for cleaning input. +* +* Constants: +* ISSO_CHECK_POST_REFERER - Will check to make sure that on POSTed +* data, the referer matches the host +* +* @author Blue Static +* @copyright Copyright ©2002 - [#]year[#], Blue Static +* @version $Revision$ +* @package ISSO +* +*/ +class BSInput +{ + /** + * An array of sanitized variables that have been cleaned for HTML tag openers and double quotes + * @var array + */ + public $in = array(); + + /** + * If we are running with magic_quotes_gpc on or off + * @var int + */ + private $magicquotes = 0; + + // ################################################################### + /** + * Constructor: set instance variables and execute input cleaning + */ + public function __construct() + { + // magic quotes + $this->magicquotes = get_magic_quotes_gpc(); + set_magic_quotes_runtime(0); + + // some debug info that's always useful + BSLoader::GetRegister()->debug('magic_quotes_gpc = ' . $this->magicquotes); + BSLoader::GetRegister()->ddebug('register_globals = ' . ini_get('register_globals')); + + $this->exec_sanitize_data(); + + if (defined('ISSO_CHECK_POST_REFERER')) + { + $this->exec_referer_check(); + } + } + + // ################################################################### + /** + * Recursive XSS cleaner + * + * @param mixed Unsanitized REQUEST data + * + * @return mixed Sanitized data + */ + public function _sanitize_input_recursive($data) + { + foreach ($data AS $key => $value) + { + if (is_array($value)) + { + $data["$key"] = $this->_sanitize_input_recursive($value); + } + else + { + if ($this->magicquotes) + { + $value = str_replace("\'", "'", $value); + } + $data["$key"] = $this->sanitize($value); + } + } + return $data; + } + + // ################################################################### + /** + * Simple way to protect against HTML attacks with Unicode support + * + * @param string Unsanitzed text + * + * @return string Properly protected text that only encodes potential threats + */ + public function sanitize($text) + { + if ($this->magicquotes) + { + return str_replace(array('<', '>', '\"', '"'), array('<', '>', '"', '"'), $text); + } + else + { + return str_replace(array('<', '>', '"'), array('<', '>', '"'), $text); + } + } + + // ################################################################### + /** + * Unicode-safe entity encoding system; similar to sanitize() + * + * @param string Unsanitized text + * + * @return string Unicode-safe sanitized text with entities preserved + */ + public function entity_encode($text) + { + $text = str_replace('&', '&', $text); + $text = $this->sanitize($text); + return $text; + } + + // ################################################################### + /** + * Takes text that has been processed for HTML and unsanitizes it + * + * @param string Text that needs to be turned back into HTML + * + * @return string Unsanitized text + */ + public function unsanitize($text) + { + return str_replace(array('<', '>', '"'), array('<', '>', '"'), $text); + } + + // ################################################################### + /** + * Smart addslashes() that only applies itself it the Magic Quotes GPC + * is off. This should only be run on database query values that come + * from ISSO->in[] input; data that needs sanitization should be run + * through ISSO->DB->escape_string() + * + * @param string Some string + * @param bool Force magic quotes to be off + * + * @return string String that has slashes added + */ + public function escape($str, $force = true) + { + if ($this->magicquotes AND !$force) + { + if (isset($this->modules[ISSO_DB_LAYER])) + { + return $this->modules[ISSO_DB_LAYER]->escape_string(str_replace(array("\'", '\"'), array("'", '"'), $str)); + } + return $str; + } + else + { + if (isset($this->modules[ISSO_DB_LAYER])) + { + return $this->modules[ISSO_DB_LAYER]->escape_string($str); + } + return addslashes($str); + } + } + + // ################################################################### + /** + * Runs through all of the input data and sanitizes it. + */ + private function exec_sanitize_data() + { + $this->in = $this->_sanitize_input_recursive(array_merge($_GET, $_POST, $_COOKIE)); + } + + // ################################################################### + /** + * Sanitize function for something other than a string (which + * everything is sanitized for if you use exec_sanitize_data(). Cleaned + * data is placed back into $isso->in; this makes it so you don't have + * to constantly intval() [etc.] data. + * + * @param array Array of elements to clean as varname => type + */ + public function input_clean_array($vars) + { + foreach ($vars AS $varname => $type) + { + $this->input_clean($varname, $type); + } + } + + // ################################################################### + /** + * Sanitize function that does a single variable as oppoesd to an array + * (see input_clean_array() for more details) + * + * @param string Variable name in $isso->in[] + * @param integer Sanitization type constant + */ + public function input_clean($varname, $type) + { + if (isset($this->in["$varname"])) + { + $this->in["$varname"] = $this->clean($this->in["$varname"], $type); + } + else + { + $this->in["$varname"] = $this->clean(null, $type); + } + + return $this->in["$varname"]; + } + + // ################################################################### + /** + * Runs ISSO->escape() on a variable on ISSO->in[]. This is just a + * short-hand wrapper so that queries can be shortened. When this is used, + * the actual value in ISSO->in[] is not changed, only the return value + * is escaped. + * + * @param string Input variable + * + * @return string Escaped input + */ + public function input_escape($varname) + { + if (isset($this->in["$varname"])) + { + return $this->escape($this->in["$varname"]); + } + else + { + return $this->escape(null); + } + } + + // ################################################################### + /** + * Cleaning function that does the work for input_clean(); this is + * moved here so it can be used to clean things that aren't in + * $isso->in[] + * + * @param mixed Data + * @param integer Sanitization type constant + * + * @return mixed Cleaned data + */ + public function clean($value, $type) + { + if (is_array($value)) + { + return $this->clean_array($value, $type); + } + + if ($type == TYPE_INT) + { + $value = intval($value); + } + else if ($type == TYPE_UINT) + { + $value = (($val = intval($value)) < 0 ? 0 : $val); + } + else if ($type == TYPE_FLOAT) + { + $value = floatval($value); + } + else if ($type == TYPE_BOOL) + { + $value = (bool)$value; + } + else if ($type == TYPE_STR) + { + $value = $value; + } + else if ($type == TYPE_STRUN) + { + $value = $this->unsanitize($value); + } + else if ($type == TYPE_NOCLEAN) + { + if ($this->magicquotes) + { + $value = str_replace(array('\"', "\'"), array('"', "'"), $value); + } + else + { + $value = $value; + } + } + else if ($type == TYPE_BIN) + { + $value = $value; + } + else + { + trigger_error('Invalid clean type specified in BSInput::clean()'); + return; + } + + return $value; + } + + // ################################################################### + /** + * Recursion function for ISSO->clean() + * + * @param array Uncleaned array + * @param integer Sanitization type constant + * + * @return array Cleaned array of data + */ + private function clean_array($array, $type) + { + foreach ($array AS $key => $value) + { + $array["$key"] = $this->clean($value, $type); + } + + return $array; + } + + // ################################################################### + /** + * Checks to see if a POST refer is actually from us + */ + public function exec_referer_check() + { + if ($_SERVER['REQUEST_METHOD'] == 'POST') + { + $host = ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_ENV['HTTP_HOST']; + + if ($host AND $_SERVER['HTTP_REFERER']) + { + $parts = parse_url($_SERVER['HTTP_REFERER']); + $ourhost = $parts['host'] . (isset($parts['port']) ? ":$parts[port]" : ''); + + if ($ourhost != $host) + { + trigger_error('No external hosts are allowed to POST to this application'); + exit; + } + BSLoader::GetRegister()->debug('remote post check = ok'); + } + else + { + BSLoader::GetRegister()->debug('remote post check = FAILED'); + } + } + } +} + +/*=====================================================================*\ +|| ################################################################### +|| # $HeadURL$ +|| # $Id$ +|| ################################################################### +\*=====================================================================*/ +?> \ No newline at end of file diff --git a/kernel.php b/kernel.php index 849a8bf..041b7e7 100644 --- a/kernel.php +++ b/kernel.php @@ -72,50 +72,6 @@ foreach ($levels AS $php => $isso) } error_reporting($newlevel); -/**#@+ -* Input cleaning type constant -*/ -/** -* Integer type -*/ -define('TYPE_INT', 1); - -/** -* Unsigned integer -*/ -define('TYPE_UINT', 2); - -/** -* Float type -*/ -define('TYPE_FLOAT', 4); - -/** -* Boolean type -*/ -define('TYPE_BOOL', 8); - -/** -* String - cleaned -*/ -define('TYPE_STR', 16); - -/** -* String - deliberate unclean -*/ -define('TYPE_STRUN', 32); - -/** -* No cleaning - here for use in API -*/ -define('TYPE_NONE', 64); - -/** -* Macro for using DB->escape_binary() without cleaning - used in API -*/ -define('TYPE_BIN', 128); -/**#@-*/ - /** * Yes, required */ @@ -134,9 +90,6 @@ define('REQ_NO', 0); * The base framework handles all loading and module management. * * Constants: -* ISSO_NO_INPUT_SANITIZE - Disables the automatic input sanitizer -* ISSO_CHECK_POST_REFERER - Will check to make sure that on POSTed -* data, the referer matches the host * ISSO_MT_START - Define the microtime() value at the top of your * script and this will calculate the total execution * time @@ -168,18 +121,6 @@ class ISSO */ private $modules = array(); - /** - * An array of sanitized variables that have been cleaned for HTML tag openers and double quotes - * @var array - */ - public $in = array(); - - /** - * If we are running with magic_quotes_gpc on or off - * @var int - */ - private $magicquotes = 0; - // ################################################################### /** * Constructor @@ -190,25 +131,6 @@ class ISSO // error reporting set_error_handler(array(&$this, '_error_handler')); - - // magic quotes - $this->magicquotes = get_magic_quotes_gpc(); - set_magic_quotes_runtime(0); - - // some debug info that's always useful - $this->debug('magic_quotes_gpc = ' . $this->magicquotes); - $this->debug('register_globals = ' . ini_get('register_globals')); - - // start input sanitize using variable_order GPC - if (!defined('ISSO_NO_INPUT_SANITIZE')) - { - $this->exec_sanitize_data(); - } - - if (defined('ISSO_CHECK_POST_REFERER')) - { - $this->exec_referer_check(); - } } // ################################################################### @@ -566,297 +488,6 @@ class ISSO $this->debuginfo[] = $message; } - // ################################################################### - /** - * Recursive XSS cleaner - * - * @param mixed Unsanitized REQUEST data - * - * @return mixed Sanitized data - */ - public function _sanitize_input_recursive($data) - { - foreach ($data AS $key => $value) - { - if (is_array($value)) - { - $data["$key"] = $this->_sanitize_input_recursive($value); - } - else - { - if ($this->magicquotes) - { - $value = str_replace("\'", "'", $value); - } - $data["$key"] = $this->sanitize($value); - } - } - return $data; - } - - // ################################################################### - /** - * Simple way to protect against HTML attacks with Unicode support - * - * @param string Unsanitzed text - * - * @return string Properly protected text that only encodes potential threats - */ - public function sanitize($text) - { - if ($this->magicquotes) - { - return str_replace(array('<', '>', '\"', '"'), array('<', '>', '"', '"'), $text); - } - else - { - return str_replace(array('<', '>', '"'), array('<', '>', '"'), $text); - } - } - - // ################################################################### - /** - * Unicode-safe entity encoding system; similar to sanitize() - * - * @param string Unsanitized text - * - * @return string Unicode-safe sanitized text with entities preserved - */ - public function entity_encode($text) - { - $text = str_replace('&', '&', $text); - $text = $this->sanitize($text); - return $text; - } - - // ################################################################### - /** - * Takes text that has been processed for HTML and unsanitizes it - * - * @param string Text that needs to be turned back into HTML - * - * @return string Unsanitized text - */ - public function unsanitize($text) - { - return str_replace(array('<', '>', '"'), array('<', '>', '"'), $text); - } - - // ################################################################### - /** - * Smart addslashes() that only applies itself it the Magic Quotes GPC - * is off. This should only be run on database query values that come - * from ISSO->in[] input; data that needs sanitization should be run - * through ISSO->DB->escape_string() - * - * @param string Some string - * @param bool Force magic quotes to be off - * - * @return string String that has slashes added - */ - public function escape($str, $force = true) - { - if ($this->magicquotes AND !$force) - { - if (isset($this->modules[ISSO_DB_LAYER])) - { - return $this->modules[ISSO_DB_LAYER]->escape_string(str_replace(array("\'", '\"'), array("'", '"'), $str)); - } - return $str; - } - else - { - if (isset($this->modules[ISSO_DB_LAYER])) - { - return $this->modules[ISSO_DB_LAYER]->escape_string($str); - } - return addslashes($str); - } - } - - // ################################################################### - /** - * Runs through all of the input data and sanitizes it. - */ - private function exec_sanitize_data() - { - $this->in = $this->_sanitize_input_recursive(array_merge($_GET, $_POST, $_COOKIE)); - } - - // ################################################################### - /** - * Sanitize function for something other than a string (which - * everything is sanitized for if you use exec_sanitize_data(). Cleaned - * data is placed back into $isso->in; this makes it so you don't have - * to constantly intval() [etc.] data. - * - * @param array Array of elements to clean as varname => type - */ - public function input_clean_array($vars) - { - foreach ($vars AS $varname => $type) - { - $this->input_clean($varname, $type); - } - } - - // ################################################################### - /** - * Sanitize function that does a single variable as oppoesd to an array - * (see input_clean_array() for more details) - * - * @param string Variable name in $isso->in[] - * @param integer Sanitization type constant - */ - public function input_clean($varname, $type) - { - if (isset($this->in["$varname"])) - { - $this->in["$varname"] = $this->clean($this->in["$varname"], $type); - } - else - { - $this->in["$varname"] = $this->clean(null, $type); - } - - return $this->in["$varname"]; - } - - // ################################################################### - /** - * Runs ISSO->escape() on a variable on ISSO->in[]. This is just a - * short-hand wrapper so that queries can be shortened. When this is used, - * the actual value in ISSO->in[] is not changed, only the return value - * is escaped. - * - * @param string Input variable - * - * @return string Escaped input - */ - public function input_escape($varname) - { - if (isset($this->in["$varname"])) - { - return $this->escape($this->in["$varname"]); - } - else - { - return $this->escape(null); - } - } - - // ################################################################### - /** - * Cleaning function that does the work for input_clean(); this is - * moved here so it can be used to clean things that aren't in - * $isso->in[] - * - * @param mixed Data - * @param integer Sanitization type constant - * - * @return mixed Cleaned data - */ - public function clean($value, $type) - { - if (is_array($value)) - { - return $this->clean_array($value, $type); - } - - if ($type == TYPE_INT) - { - $value = intval($value); - } - else if ($type == TYPE_UINT) - { - $value = (($val = intval($value)) < 0 ? 0 : $val); - } - else if ($type == TYPE_FLOAT) - { - $value = floatval($value); - } - else if ($type == TYPE_BOOL) - { - $value = (bool)$value; - } - else if ($type == TYPE_STR) - { - $value = $value; - } - else if ($type == TYPE_STRUN) - { - $value = $this->unsanitize($value); - } - else if ($type == TYPE_NOCLEAN) - { - if ($this->magicquotes) - { - $value = str_replace(array('\"', "\'"), array('"', "'"), $value); - } - else - { - $value = $value; - } - } - else if ($type == TYPE_BIN) - { - $value = $value; - } - else - { - trigger_error('Invalid clean type `' . $type . '` specified', E_USER_ERROR); - } - - return $value; - } - - // ################################################################### - /** - * Recursion function for ISSO->clean() - * - * @param array Uncleaned array - * @param integer Sanitization type constant - * - * @return array Cleaned array of data - */ - private function clean_array($array, $type) - { - foreach ($array AS $key => $value) - { - $array["$key"] = $this->clean($value, $type); - } - - return $array; - } - - // ################################################################### - /** - * Checks to see if a POST refer is actually from us - */ - public function exec_referer_check() - { - if ($_SERVER['REQUEST_METHOD'] == 'POST') - { - $host = ($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_ENV['HTTP_HOST']; - - if ($host AND $_SERVER['HTTP_REFERER']) - { - $parts = parse_url($_SERVER['HTTP_REFERER']); - $ourhost = $parts['host'] . (isset($parts['port']) ? ":$parts[port]" : ''); - - if ($ourhost != $host) - { - trigger_error('No external hosts are allowed to POST to this application', E_USER_ERROR); - } - $this->debug('remote post check = ok'); - } - else - { - $this->debug('remote post check = FAILED'); - } - } - } - // ################################################################### /** * Constructs a debug information box that contains various debugging -- 2.22.5