addslashes_deep负责对用户提交的数据进行转义,以防SQL注入,然而分析addslashes_deep函数后我们就可以发现,该函数只处理数组的值,对数组的key是完全不作任何过滤的,这直接导致了漏洞。
一个漏洞示例:
include_once '../krumo/class.krumo.php';
header("Content-type: text/html; charset=utf-8");
// krumo::backtrace();
/**
* 递归方式的对变量中的特殊字符进行转义
*
* @access public
* @param mix $value
*
* @return mix
*/
function addslashes_deep($value)
{
if (empty($value))
{
return $value;
}
else
{
return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
}
}
/**
* 将对象成员变量或者数组的特殊字符进行转义
*
* @access public
* @param mix $obj 对象或者数组
*
*
* @return mix 对象或者数组
*/
function addslashes_deep_obj($obj)
{
if (is_object($obj) == true)
{
foreach ($obj AS $key => $val)
{
if ( ($val) == true)
{
$obj->$key = addslashes_deep_obj($val);
}
else
{
$obj->$key = addslashes_deep($val);
}
}
}
else
{
$obj = addslashes_deep($obj);
}
return $obj;
}
/**
* 递归方式的对变量中的特殊字符去除转义
*
* @access public
* @param mix $value
*
* @return mix
*/
function stripslashes_deep($value)
{
if (empty($value))
{
return $value;
}
else
{
return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
}
echo '原来的线性数组:
';
$arr = array('I\'m hankcs');
krumo($arr);
echo '转义后:
';
krumo(addslashes_deep($arr));
echo '假如使用k-v数组:
';
$arr = array('I\'m hankcs' => 'but who\'re you?');
krumo($arr);
echo '转义后:
';
krumo(addslashes_deep($arr));
结果I'm hankcs中的'根本没有被转义!
一个可用的修正补丁:
include_once '../krumo/class.krumo.php';
header("Content-type: text/html; charset=utf-8");
// krumo::backtrace();
/**
* 递归方式的对变量中的特殊字符进行转义
*
* @access public
* @param mix $value
* @author hankcs
*
* @return mix
*/
function addslashes_deep($value)
{
if (empty($value))
{
return $value;
}
if(is_array($value))
{
foreach((array)$value as $k=>$v)
{
unset($value[$k]);
$k = addslashes($k);
if(is_array($v))
$value[$k] = addslashes_deep($v);
else
$value[$k] = addslashes($v);
}
}
else
{
$value = addslashes($value);
}
return $value;
}
/**
* 将对象成员变量或者数组的特殊字符进行转义
*
* @access public
* @param mix $obj 对象或者数组
* @author hankcs
*
* @return mix 对象或者数组
*/
function addslashes_deep_obj($obj)
{
if (is_object($obj) == true)
{
foreach ($obj AS $key => $val)
{
if ( ($val) == true)
{
$obj->$key = addslashes_deep_obj($val);
}
else
{
$obj->$key = addslashes_deep($val);
}
}
}
else
{
$obj = addslashes_deep($obj);
}
return $obj;
}
/**
* 递归方式的对变量中的特殊字符去除转义
*
* @access public
* @param mix $value
*
* @return mix
*/
function stripslashes_deep($value)
{
if (empty($value))
{
return $value;
}
if(is_array($value))
{
foreach((array)$value as $k=>$v)
{
unset($value[$k]);
$k = stripslashes($k);
if(is_array($v))
{
$value[$k] = stripslashes_deep($v);
}
else
{
$value[$k] = stripslashes($v);
}
}
}
else
{
$value = stripslashes($value);
}
return $value;
}
echo '原来的线性数组:
';
$arr = array('I\'m hankcs');
krumo($arr);
echo '转义后:
';
krumo(addslashes_deep($arr));
echo '假如使用k-v数组:
';
$arr = array('I\'m hankcs' => 'but who\'re you?');
krumo($arr);
echo '转义后:
';
krumo(addslashes_deep($arr));
echo '使用obj转义:';
krumo(addslashes_deep_obj($arr));
echo '先转义再还原:';
krumo(stripslashes_deep(addslashes_deep($arr)));
结果正常,至于还有没有潜在的问题,就交给屏幕前的你帮忙测试吧。