addslashes_deep负责对用户提交的数据进行转义,以防SQL注入,然而分析addslashes_deep函数后我们就可以发现,该函数只处理数组的值,对数组的key是完全不作任何过滤的,这直接导致了漏洞。
一个漏洞示例:
<?php 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 '原来的线性数组:<br>'; $arr = array('I\'m hankcs'); krumo($arr); echo '转义后:<br>'; krumo(addslashes_deep($arr)); echo '假如使用k-v数组:<br>'; $arr = array('I\'m hankcs' => 'but who\'re you?'); krumo($arr); echo '转义后:<br>'; krumo(addslashes_deep($arr));
结果I'm hankcs中的'根本没有被转义!
一个可用的修正补丁:
<?php 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 '原来的线性数组:<br>'; $arr = array('I\'m hankcs'); krumo($arr); echo '转义后:<br>'; krumo(addslashes_deep($arr)); echo '假如使用k-v数组:<br>'; $arr = array('I\'m hankcs' => 'but who\'re you?'); krumo($arr); echo '转义后:<br>'; krumo(addslashes_deep($arr)); echo '使用obj转义:'; krumo(addslashes_deep_obj($arr)); echo '先转义再还原:'; krumo(stripslashes_deep(addslashes_deep($arr)));
结果正常,至于还有没有潜在的问题,就交给屏幕前的你帮忙测试吧。
请问大侠用这个函数干什么?