首页 PHP 正文
1093

PHP过滤GET、POST参数(解决SQL注入)

先来看一段很流行的过滤代码:
function filter($input)
{
    //如果magic_quotes_gpc=Off(php没有自动为特殊符号转义),那么就开始处理
    if (!get_magic_quotes_gpc()) {
        //判断$input是否为数组
        if (is_array($input)) {
            //如果$input是数组,那么就处理它的每一个单无
            foreach ($input as $key=>$value) {
                $input [$key] = addslashes($value);
            }
        }else{
            //如果$input不是数组,那么就仅处理一次
            $input = addslashes($input);
        }
    } else {
        //如果magic_quotes_gpc=On(php自动为特殊符号转义),那么就不处理
    }
    return $input;
}

$arr = array('hi',"i'm a boy");
$out = filter($arr);
var_dump($out);/*array(2) {
  [0]=> string(2) "hi"
  [1]=>string(10) "i\'m a boy"
}
*/
看测试结果,好像很令人满意,效果还不错。 但是这里有两点个人认为不太完美的地方。
第一,addslashes这个函数只能对单引号(')、双引号(")、反斜线(\)与 NUL(NULL 字符)进行转义,而黑客可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截(摘自网上)。所以网上有高手建议使用mysql_escape_string进行过滤(注意还有一个功能相似的mysql_real_escape_string,基本差不多)。当然mysql_escape_string只能针对mysql数据库了,如果是其它数据库,那看样子只能用addslashes了。
第二,这段代码只能对一维数组进行过滤,这让我这种强迫症重度患者很难受,要知道用户POST过来的数据有时也是数组,那么$_POST就有可能是二维数组了。
所以针对以上两个不完美的地方,我稍加修改了一下代码:
function filter($input)
{
    //如果magic_quotes_gpc=Off(php没有自动为特殊符号转义),那么就开始处理
    if (!get_magic_quotes_gpc()) {
        //判断$input是否为数组
        if (is_array($input)) {
            //如果$input是数组,那么就处理它的每一个单无
            foreach ($input as $key=>$value) {
                $input [$key] = filter($value);//利用递归进行多维数组的转义
            }
        }else{
            //如果$input不是数组,那么就仅处理一次
            $input = mysql_escape_string($input);
        }
    } else {
        //如果magic_quotes_gpc=On(php自动为特殊符号转义),那么就不处理,注意也不能用mysql_escape_string进行转义
        
    }
    return $input;
}

$arr = array('hi',"I'm a boy",array("he's a man",array("she's a girl")));
$out = filter($arr);
var_dump($out);
/*
array(3) { [0]=> string(2) "hi" [1]=> string(10) "I\'m a boy" [2]=> array(2) { [0]=> string(11) "he\'s a man" [1]=> array(1) { [0]=> string(13) "she\'s a girl" } } } */

正在加载评论...