summaryrefslogtreecommitdiffstats
path: root/system/libraries/Input.php
diff options
context:
space:
mode:
authorDerek Allard <derek.allard@ellislab.com>2008-05-12 23:37:04 +0200
committerDerek Allard <derek.allard@ellislab.com>2008-05-12 23:37:04 +0200
commit15dcf49a0ea6895cbf009dc15277858cfdd422ef (patch)
tree5a00d6edf1c4a940988f815208d2a744753f21c6 /system/libraries/Input.php
parent5fe155ecd05af4ee68ef093200fb6a241baa89ce (diff)
removed an ereg from config
added a qualifier to a str_replace for \t in Input changed substr to strncmp in Codeigniter.php and directory_map function added braces in an if statement of unit test Removed "scripts" from the auto-load search path. Scripts were deprecated in Version 1.4.1 (September 21, 2006). If you still need to use them for legacy reasons, they must now be manually loaded in each Controller.
Diffstat (limited to 'system/libraries/Input.php')
-rw-r--r--system/libraries/Input.php222
1 files changed, 112 insertions, 110 deletions
diff --git a/system/libraries/Input.php b/system/libraries/Input.php
index 9b012d320..e3515661d 100644
--- a/system/libraries/Input.php
+++ b/system/libraries/Input.php
@@ -32,7 +32,7 @@ class CI_Input {
var $ip_address = FALSE;
var $user_agent = FALSE;
var $allow_get_array = FALSE;
-
+
/**
* Constructor
*
@@ -40,19 +40,19 @@ class CI_Input {
* and whether to allow the $_GET array
*
* @access public
- */
+ */
function CI_Input()
- {
+ {
log_message('debug', "Input Class Initialized");
-
+
$CFG =& load_class('Config');
$this->use_xss_clean = ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE;
- $this->allow_get_array = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE;
+ $this->allow_get_array = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE;
$this->_sanitize_globals();
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Sanitize Globals
*
@@ -72,7 +72,7 @@ class CI_Input {
// Would kind of be "wrong" to unset any of these GLOBALS
$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN');
-
+
// Unset globals for security.
// This is effectively the same as register_globals = off
foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global)
@@ -92,7 +92,7 @@ class CI_Input {
{
unset($GLOBALS[$key]);
}
-
+
if (is_array($val))
{
foreach($val as $k => $v)
@@ -103,7 +103,7 @@ class CI_Input {
}
}
}
- }
+ }
}
}
@@ -122,30 +122,30 @@ class CI_Input {
}
}
}
-
+
// Clean $_POST Data
if (is_array($_POST) AND count($_POST) > 0)
{
foreach($_POST as $key => $val)
- {
+ {
$_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
- }
+ }
}
-
+
// Clean $_COOKIE Data
if (is_array($_COOKIE) AND count($_COOKIE) > 0)
{
foreach($_COOKIE as $key => $val)
- {
+ {
$_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
- }
+ }
}
-
+
log_message('debug', "Global POST and COOKIE data sanitized");
- }
-
+ }
+
// --------------------------------------------------------------------
-
+
/**
* Clean Input Data
*
@@ -155,7 +155,7 @@ class CI_Input {
* @access private
* @param string
* @return string
- */
+ */
function _clean_input_data($str)
{
if (is_array($str))
@@ -167,25 +167,25 @@ class CI_Input {
}
return $new_array;
}
-
+
// We strip slashes if magic quotes is on to keep things consistent
if (get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
-
+
// Should we filter the input data?
if ($this->use_xss_clean === TRUE)
{
$str = $this->xss_clean($str);
}
-
+
// Standardize newlines
return preg_replace("/\015\012|\015|\012/", "\n", $str);
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Clean Keys
*
@@ -198,7 +198,7 @@ class CI_Input {
* @return string
*/
function _clean_input_keys($str)
- {
+ {
if (! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
exit('Disallowed Key Characters.');
@@ -208,7 +208,7 @@ class CI_Input {
}
// --------------------------------------------------------------------
-
+
/**
* Fetch an item from the GET array
*
@@ -218,7 +218,7 @@ class CI_Input {
* @return string
*/
function get($index = '', $xss_clean = FALSE)
- {
+ {
if (! isset($_GET[$index]))
{
return FALSE;
@@ -229,7 +229,7 @@ class CI_Input {
if (is_array($_GET[$index]))
{
foreach($_GET[$index] as $key => $val)
- {
+ {
$_GET[$index][$key] = $this->xss_clean($val);
}
}
@@ -241,9 +241,9 @@ class CI_Input {
return $_GET[$index];
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Fetch an item from the POST array
*
@@ -253,7 +253,7 @@ class CI_Input {
* @return string
*/
function post($index = '', $xss_clean = FALSE)
- {
+ {
if (! isset($_POST[$index]))
{
return FALSE;
@@ -264,7 +264,7 @@ class CI_Input {
if (is_array($_POST[$index]))
{
foreach($_POST[$index] as $key => $val)
- {
+ {
$_POST[$index][$key] = $this->xss_clean($val);
}
}
@@ -276,9 +276,9 @@ class CI_Input {
return $_POST[$index];
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Fetch an item from the COOKIE array
*
@@ -303,7 +303,7 @@ class CI_Input {
{
$cookie[$key] = $this->xss_clean($val);
}
-
+
return $cookie;
}
else
@@ -318,7 +318,7 @@ class CI_Input {
}
// --------------------------------------------------------------------
-
+
/**
* Fetch an item from the SERVER array
*
@@ -328,7 +328,7 @@ class CI_Input {
* @return string
*/
function server($index = '', $xss_clean = FALSE)
- {
+ {
if (! isset($_SERVER[$index]))
{
return FALSE;
@@ -338,12 +338,12 @@ class CI_Input {
{
return $this->xss_clean($_SERVER[$index]);
}
-
+
return $_SERVER[$index];
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Fetch the IP Address
*
@@ -356,7 +356,7 @@ class CI_Input {
{
return $this->ip_address;
}
-
+
if ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
{
$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
@@ -373,29 +373,29 @@ class CI_Input {
{
$this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
-
+
if ($this->ip_address === FALSE)
{
$this->ip_address = '0.0.0.0';
return $this->ip_address;
}
-
+
if (strstr($this->ip_address, ','))
{
$x = explode(',', $this->ip_address);
$this->ip_address = end($x);
}
-
+
if (! $this->valid_ip($this->ip_address))
{
$this->ip_address = '0.0.0.0';
}
-
+
return $this->ip_address;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Validate IP Address
*
@@ -408,7 +408,7 @@ class CI_Input {
function valid_ip($ip)
{
$ip_segments = explode('.', $ip);
-
+
// Always 4 segments needed
if (count($ip_segments) != 4)
{
@@ -429,12 +429,12 @@ class CI_Input {
return FALSE;
}
}
-
+
return TRUE;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* User Agent
*
@@ -447,14 +447,14 @@ class CI_Input {
{
return $this->user_agent;
}
-
+
$this->user_agent = (! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
-
+
return $this->user_agent;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Filename Security
*
@@ -497,13 +497,13 @@ class CI_Input {
"%3f", // ?
"%3b", // ;
"%3d" // =
- );
-
- return stripslashes(str_replace($bad, '', $str));
+ );
+
+ return stripslashes(str_replace($bad, '', $str));
}
-
+
// --------------------------------------------------------------------
-
+
/**
* XSS Clean
*
@@ -542,10 +542,10 @@ class CI_Input {
{
$str[$key] = $this->xss_clean($str[$key]);
}
-
+
return $str;
}
-
+
/*
* Remove Null Characters
*
@@ -572,7 +572,7 @@ class CI_Input {
*
*/
$str = preg_replace('#(&\#?[0-9a-z]+)[\x00-\x20]*;?#i', "\\1;", $str);
-
+
/*
* Validate UTF16 two byte encoding (x00)
*
@@ -586,7 +586,7 @@ class CI_Input {
*/
$str = str_replace($this->xss_hash(), '&', $str);
-
+
/*
* URL Decode
*
@@ -596,9 +596,9 @@ class CI_Input {
*
* Note: Use rawurldecode() so it does not remove plus signs
*
- */
+ */
$str = rawurldecode($str);
-
+
/*
* Convert character entities to ASCII
*
@@ -607,15 +607,15 @@ class CI_Input {
* these are the ones that will pose security problems.
*
*/
-
+
$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_attribute_conversion'), $str);
$str = preg_replace_callback("/<([\w]+)[^>]*>/si", array($this, '_html_entity_decode_callback'), $str);
/*
-
+
Old Code that when modified to use preg_replace()'s above became more efficient memory-wise
-
+
if (preg_match_all("/[a-z]+=([\'\"]).*?\\1/si", $str, $matches))
{
for ($i = 0; $i < count($matches[0]); $i++)
@@ -639,7 +639,7 @@ class CI_Input {
}
}
*/
-
+
/*
* Convert all tabs to spaces
*
@@ -649,12 +649,14 @@ class CI_Input {
* so we use str_replace.
*
*/
-
- $str = str_replace("\t", " ", $str);
+
+ if (strpos($str, "\t") !== FALSE) {
+ $str = str_replace("\t", " ", $str);
+ }
/*
* Not Allowed Under Any Conditions
- */
+ */
$bad = array(
'document.cookie' => '[removed]',
'document.write' => '[removed]',
@@ -677,12 +679,12 @@ class CI_Input {
"expression\s*\(" => '[removed]', // CSS and IE
"Redirect\s+302" => '[removed]'
);
-
+
foreach ($bad as $key => $val)
{
$str = preg_replace("#".$key."#i", $val, $str);
}
-
+
/*
* Makes PHP tags safe
*
@@ -692,16 +694,16 @@ class CI_Input {
*
* But it doesn't seem to pose a problem.
*
- */
+ */
$str = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
-
+
/*
* Compact any exploded words
*
* This corrects words like: j a v a s c r i p t
* These words are compacted back to their correct state.
*
- */
+ */
$words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window');
foreach ($words as $word)
{
@@ -710,31 +712,31 @@ class CI_Input {
{
$temp .= substr($word, $i, 1)."\s*";
}
-
+
// We only want to do this when it is followed by a non-word character
// That way valid stuff like "dealer to" does not become "dealerto"
$str = preg_replace('#('.substr($temp, 0, -3).')(\W)#ise', "preg_replace('/\s+/s', '', '\\1').'\\2'", $str);
}
-
+
/*
* Remove disallowed Javascript in links or img tags
*/
do
{
$original = $str;
-
+
if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '</a>') !== FALSE) OR
preg_match("/<\/a>/i", $str))
{
$str = preg_replace_callback("#<a.*?</a>#si", array($this, '_js_link_removal'), $str);
}
-
+
if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && stripos($str, '<img') !== FALSE) OR
preg_match("/img/i", $str))
{
$str = preg_replace_callback("#<img.*?".">#si", array($this, '_js_img_removal'), $str);
}
-
+
if ((version_compare(PHP_VERSION, '5.0', '>=') === TRUE && (stripos($str, 'script') !== FALSE OR stripos($str, 'xss') !== FALSE)) OR
preg_match("/(script|xss)/i", $str))
{
@@ -742,7 +744,7 @@ class CI_Input {
}
}
while($original != $str);
-
+
unset($original);
/*
@@ -752,10 +754,10 @@ class CI_Input {
* the event handler and anything up to the closing >,
* but it's unlikely to be a problem.
*
- */
+ */
$event_handlers = array('onblur','onchange','onclick','onfocus','onload','onmouseover','onmouseup','onmousedown','onselect','onsubmit','onunload','onkeypress','onkeydown','onkeyup','onresize', 'xmlns');
$str = preg_replace("#<([^>]+)(".implode('|', $event_handlers).")([^>]*)>#iU", "&lt;\\1\\2\\3&gt;", $str);
-
+
/*
* Sanitize naughty HTML elements
*
@@ -765,9 +767,9 @@ class CI_Input {
* So this: <blink>
* Becomes: &lt;blink&gt;
*
- */
+ */
$str = preg_replace('#<(/*\s*)(alert|applet|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|layer|link|meta|object|plaintext|style|script|textarea|title|xml|xss)([^>]*)>#is', "&lt;\\1\\2\\3&gt;", $str);
-
+
/*
* Sanitize naughty scripting elements
*
@@ -782,14 +784,14 @@ class CI_Input {
*
*/
$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
-
+
/*
* Final clean up
*
* This adds a bit of extra precaution in case
* something got through the above filters
*
- */
+ */
$bad = array(
'document.cookie' => '[removed]',
'document.write' => '[removed]',
@@ -812,19 +814,19 @@ class CI_Input {
"expression\s*\(" => '[removed]', // CSS and IE
"Redirect\s+302" => '[removed]'
);
-
+
foreach ($bad as $key => $val)
{
$str = preg_replace("#".$key."#i", $val, $str);
}
-
-
+
+
log_message('debug', "XSS Filtering completed");
return $str;
}
// --------------------------------------------------------------------
-
+
/**
* Random Hash for protecting URLs
*
@@ -832,22 +834,22 @@ class CI_Input {
* @return string
*/
function xss_hash()
- {
+ {
if ($this->xss_hash == '')
{
if (phpversion() >= 4.2)
mt_srand();
else
mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);
-
+
$this->xss_hash = md5(time() + mt_rand(0, 1999999999));
}
-
+
return $this->xss_hash;
}
// --------------------------------------------------------------------
-
+
/**
* JS Link Removal
*
@@ -864,7 +866,7 @@ class CI_Input {
{
return preg_replace("#<a.+?href=.*?(alert\(|alert&\#40;|javascript\:|window\.|document\.|\.cookie|<script|<xss).*?\>.*?</a>#si", "", $match[0]);
}
-
+
/**
* JS Image Removal
*
@@ -883,7 +885,7 @@ class CI_Input {
}
// --------------------------------------------------------------------
-
+
/**
* Attribute Conversion
*
@@ -897,7 +899,7 @@ class CI_Input {
{
return str_replace('>', '&lt;', $match[0]);
}
-
+
// --------------------------------------------------------------------
/**
@@ -918,7 +920,7 @@ class CI_Input {
}
// --------------------------------------------------------------------
-
+
/**
* HTML Entities Decode
*
@@ -937,7 +939,7 @@ class CI_Input {
/* -------------------------------------------------
/* Replacement for html_entity_decode()
/* -------------------------------------------------*/
-
+
/*
NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the
character set, and the PHP developers said they were not back porting the
@@ -946,30 +948,30 @@ class CI_Input {
function _html_entity_decode($str, $charset='UTF-8')
{
if (stristr($str, '&') === FALSE) return $str;
-
+
// The reason we are not using html_entity_decode() by itself is because
// while it is not technically correct to leave out the semicolon
// at the end of an entity most browsers will still interpret the entity
// correctly. html_entity_decode() does not convert entities without
// semicolons, so we are left with our own little solution here. Bummer.
-
+
if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>=')))
{
$str = html_entity_decode($str, ENT_COMPAT, $charset);
$str = preg_replace('~&#x([0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str);
return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str);
}
-
+
// Numeric Entities
$str = preg_replace('~&#x([0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str);
$str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str);
-
+
// Literal Entities - Slightly slow so we do another check
if (stristr($str, '&') === FALSE)
{
$str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES)));
}
-
+
return $str;
}