2017-08-10 47 views
-1

我有一個PHP 5.3.29和MySQL 5.6.35的應用程序。 我用SQLQUERY來執行SQL指令,然後用準備好的語句切換到PDO以避免SQL-i,但是當我用ZAP 2.6.0測試我的應用程序時,我可以確認SQL-I仍然發生,儘管使用了「 PDO「和」準備「。 我在MySQL中激活了常規日誌,並查找了所有已執行的語句。PDO不過濾SQL注入

我的代碼是:

function cerrar_sesion($usuario) { 
$pdo = new 
PDO("mysql:"."host=".DB_SERVIDOR.";"."dbname=".DB_BASEDATOS,DB_USUARIO, DB_CLAVE); 
$query = $pdo->prepare('UPDATE ADMIN_USUARIO SET USERID=\' \' WHERE C_USUARIO= :usuario'); 
$query->bindParam(':usuario',$usuario,PDO::PARAM_INT); 
$query->execute(); 
$pdo = null; 
......... 
} 

檢查數據庫日誌,我看到參數 「C_USUARIO」 改變,下面的3個系從MySQL日誌提取:

227726查詢UPDATE ADMIN_USUARIO SET USERID = ' 'WHERE C_USUARIO = '54/2' 227730查詢UPDATE SET ADMIN_USUARIO USERID =' 'WHERE C_USUARIO = '108/2' 227732查詢UPDATE SET ADMIN_USUARIO USERID =''WHERE C_USUARIO = '108/2'

注意事項C_USUARIO值should't有「/ 2」,這是由ZAP注入

我預計PDO,以防止注射,但這種情況並非如此,我怎麼能做到這一點使用PDO ?

請幫助我,我會讚賞它。

+0

只是...什麼? 「我可以確認SQL-I仍然發生」?我假設你的意思是SQL注入?你關閉了[Emulate Prepares](http://php.net/manual/en/pdo.setattribute.php)嗎?我不確定MySQL在準備語句時實際記錄了什麼,所以這可能是完全正確的輸出。 –

+0

你能更清楚你的問題嗎?我很抱歉,我只是不理解發生什麼事情而不是你期待的事情。 –

回答

0

默認情況下,PDO通過將綁定變量插入到SQL查詢字符串中,然後直接執行該SQL而不使用參數,來「模擬」預準備語句。

PDO確實應用了正確的轉義,因爲它在查詢中插入了您的變量,因此它對於SQL注入來說是安全的。

如果你想真正的參數化查詢,禁用仿真:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

更多信息請參見http://php.net/manual/en/pdo.setattribute.php

如果您禁用仿真,您的MySQL查詢日誌將顯示PREPARE和EXECUTE作爲單獨的步驟。但是MySQL也會記錄完整的查詢,包括參數值。這也是安全的,這只是爲了記錄MySQL而做的一個方便,因爲用值顯示查詢很有用。請參閱https://stackoverflow.com/a/210693/20860的答案中的示例。