专注于高品质PHP技术等信息服务于一体 [STIEMAP] [RSS]

百度提供的广告:
sql
当前位置:首页 > 技术文档 > sql >  > 
Sql 注入问题在弱类型语言如PHP ASP 中表现的稍多一些。

Sql 注入问题在弱类型语言如PHP ASP 中表现的稍多一些。在强类型语言JAVA .NET 方面需要注意的就比较少。


需要注意,如:int Guid 类型主键,本身就是一种数据类型,就算,程序没有对这些参数进行过滤,但也无


法被人攻击,如:int aid=1; ?aid=1 and or 1=1 程序取出的是 aid="1 and or 1=1", "1 and or 1=1"是无


法转为int 数据类型的,会报数型转换异常。但其它类型就不容乐观,如String 字符串类型在处理上必须和弱


类型一样。在PHP中,所有的参数都被要被安全检查,最常用的方法就是使用替换字符串中所有的“'”“"”。使用


intval()来转载参数为int类型。下面是一段检查sql安全的PHP代码,来源自DEDECMS 核心类库。



<?php


//SQL语句过滤程序,由80sec提供,这里作了适当的修改


function CheckSql($db_string,$querytype='select')


{


    global $cfg_cookie_encode;


    $clean = '';


    $error='';


    $old_pos = 0;


    $pos = -1;


    $log_file = DEDEINC.'/../data/'.md5($cfg_cookie_encode).'_safe.txt';


    $userIP = GetIP();


    $getUrl = GetCurUrl();



    //如果是普通查询语句,直接过滤一些特殊语法


    if($querytype=='select')


    {


        $notallow1 = "[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}";



        //$notallow2 = "--|/\*";


        if(eregi($notallow1,$db_string))


        {


            fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");


            exit("<font size='5' color='red'>Safe Alert: Request Error step 1 !</font>");


        }


    }



    //完整的SQL检查


    while (true)


    {


        $pos = strpos($db_string, '\'', $pos + 1);


        if ($pos === false)


        {


            break;


        }


        $clean .= substr($db_string, $old_pos, $pos - $old_pos);


        while (true)


        {


            $pos1 = strpos($db_string, '\'', $pos + 1);


            $pos2 = strpos($db_string, '\\', $pos + 1);


            if ($pos1 === false)


            {


                break;


            }


            elseif ($pos2 == false || $pos2 > $pos1)


            {


                $pos = $pos1;


                break;


            }


            $pos = $pos2 + 1;


        }


        $clean .= '$s$';


        $old_pos = $pos + 1;


    }


    $clean .= substr($db_string, $old_pos);


    $clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));



    //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它


    if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0)


    {


        $fail = true;


        $error="union detect";


    }



    //发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们


    elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false)


    {


        $fail = true;


        $error="comment detect";


    }



    //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库


    elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0)


    {


        $fail = true;


        $error="slown down detect";


    }


    elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0)


    {


        $fail = true;


        $error="slown down detect";


    }


    elseif (strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0)


    {


        $fail = true;


        $error="file fun detect";


    }


    elseif (strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0)


    {


        $fail = true;


        $error="file fun detect";


    }



    //老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息


    elseif (preg_match('~\([^)]*?select~s', $clean) != 0)


    {


        $fail = true;


        $error="sub select detect";


    }


    if (!empty($fail))


    {


        fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||$error\r\n");


        exit("<font size='5' color='red'>Safe Alert: Request Error step 2!</font>");


    }


    else


    {


        return $db_string;


    }


}


?>