php:如何防止来自$ _POST的SQL注入

时间:2010-11-22 02:11:12

标签: php mysql sql-injection firebird

我有一些PHP脚本,我认为这有很多错误。因为我在连接和SQL注入方面的知识有限。在第一次我没有任何麻烦,因为这个脚本使用PHP-Mysql。

但在我尝试转入Interbase后,我遇到了很多麻烦。 请帮助确定我的错误。

我的以下查询:

$sLimit = "";
        if ( isset( $_POST['iDisplayStart'] ) )
        {
                $sLimit = " FIRST ".$_POST['iDisplayStart']." SKIP ".$_POST['iDisplayLength'];
        }
$sOrder ="";
        $sOrder = " ORDER BY LINE_NAME ";
$sWhere = "";
        if (postVar('sSearch') !="" )
        {
                 $sWhere = " WHERE (LINE_NAME LIKE '%".$_POST['sSearch']."%' OR
                                MODEL_ONLY LIKE '%".$_POST['sSearch']."%' OR ".
                               " VER_ONLY LIKE '%".$_POST['sSearch']."%' OR ".
                               " LOT_SIZE LIKE '%".$_POST['sSearch']."%' OR ".
                               " START_SERIAL LIKE '%".$_POST['sSearch']."%' OR ".
                               " SERIAL_NO_LOW LIKE '%".$_POST['sSearch']."%' OR ".
                               " SERIAL_NO_UP LIKE '%".$_POST['sSearch']."%' OR ".
                               " PROD_NO LIKE '%".$_POST['sSearch']."%' OR ".
                               " PROD_DATE LIKE '%".$_POST['sSearch']."%') ";
        }
 $sQuery = "SELECT LINE_NAME, MODEL_ONLY, VER_ONLY, PROD_NO, 
                   LOT_SIZE, START_SERIAL, SERIAL_NO_LOW, SERIAL_NO_UP, PROD_DATE 
            FROM DOC_TO".$sWhere.$sOrder.$sLimit.";";
 $rResult = ibase_query( $sQuery) or _doError(_ERROR30 . ' (<small>' . htmlspecialchars($sql) . '</small>): ' . ibase_errmsg() );  

 $sQuery = "SELECT COUNT(*) FROM (SELECT LINE_NAME, MODEL_ONLY, VER_ONLY, PROD_NO,
                                         LOT_SIZE, START_SERIAL, SERIAL_NO_LOW, SERIAL_NO_UP, PROD_DATE 
                                  FROM DOC_TO'.$sWhere.$sOrder.$sLimit.')";
 $rResultFilterTotal = ibase_query( $sQuery) or _doError(_ERROR30 . ' (<small>' . htmlspecialchars($sql) . '</small>): ' . ibase_errmsg() );
 $aResultFilterTotal = ibase_fetch_assoc($rResultFilterTotal);
 $iFilteredTotal = $aResultFilterTotal[0];

注意:我需要了解更多关于连接的信息。谢谢你的进步。


错误:

Dynamic SQL Error SQL error code = -104 Token unknown - line 3, column 39 '.. ORDER BY LINE_NAME ..'

2 个答案:

答案 0 :(得分:3)

看起来好像可以运行,所以如果失败请描述一下。

然而,其中有一个立即可见的错误:在行

$sQuery = "SELECT COUNT(*) FROM (SELECT LINE_NAME, MODEL_ONLY, VER_ONLY, PROD_NO,
                                         LOT_SIZE, START_SERIAL, SERIAL_NO_LOW, SERIAL_NO_UP, PROD_DATE 
                                  FROM DOC_TO'.$sWhere.$sOrder.$sLimit.')";

您正在使用双引号启动一个字符串,并尝试使用单引号中断字符串,这将无效。所以代码必须是:

$sQuery = "SELECT COUNT(*) FROM (SELECT LINE_NAME, MODEL_ONLY, VER_ONLY, PROD_NO,
                                         LOT_SIZE, START_SERIAL, SERIAL_NO_LOW, SERIAL_NO_UP, PROD_DATE 
                                  FROM DOC_TO".$sWhere.$sOrder.$sLimit.")";

除了您的环境之外,您的代码中还存在一个重要的安全漏洞:例如,在

行中
$sLimit = " FIRST ".$_POST['iDisplayStart']." SKIP ".$_POST['iDisplayLength'];

您正在使用$ _POST将其直接放入SQL查询中,这会打开一个所谓的SQL注入安全漏洞。

答案 1 :(得分:-1)

我从AndreKR的指导中找到答案:

$sLimit = "";
        if ( isset( $_POST['iDisplayStart'] ) )
        {
                settype($iDisplayStart,'integer');
                $iDisplayStart = $_POST['iDisplayStart'];
                $iDisplayLength = $_POST['iDisplayLength'];
                $sLimit = sprintf(" FIRST ".$iDisplayStart." SKIP ".$iDisplayLength);
        }

并更改所有$ _POST:

'%".$_POST['sSearch_0']."%'
into
''%".$_POST['sSearch_0']."%''   //this to prevent injection For databases Like Oracle, DB2, MS SQL, Firebird

并改变:

$sQuery = "SELECT COUNT(*) FROM(......)
into
$sQuery = "SELECT COUNT(*) AS DCOUNT FROM DOC_TO".$sWhere.$sLimit.";"; //delete $sOrder

$aResultFilterTotal = ibase_fetch_assoc($rResultFilterTotal);
$iFilteredTotal = $aResultFilterTotal['DCOUNT'];  //change from ......[0]

并在最后一个php页面添加:

ibase_free_result($aResultTotal);
?>