【问题标题】:PDO not filter SQL InjectionPDO 不过滤 SQL 注入
【发布时间】:2018-01-19 01:19:51
【问题描述】:

我有一个使用 PHP 5.3.29 和 MySQL 5.6.35 的应用程序。 我使用 SQLQUERY 执行 SQL 指令,然后使用准备好的语句更改为 PDO 以避免 SQL-i,但是当我使用 ZAP 2.6.0 测试我的应用程序时,我可以确认 SQL-I 仍然发生,尽管使用了“PDO ”和“准备”。 我在 MySQL 上激活了通用日志并查找了所有已执行的语句。

我的代码是:

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 ADMIN_USUARIO SET USERID=' ' WHERE C_USUARIO= '108/2' 227732 查询 UPDATE ADMIN_USUARIO SET USERID=' ' WHERE C_USUARIO 108/2'

注意 C_USUARIO 的值不应包含由 ZAP 注入的“/2”

我希望 PDO 能够阻止注入,但事实并非如此,我如何使用 PDO 做到这一点?

请帮帮我,我会很感激的。

【问题讨论】:

  • 只是……什么? “我可以确认 SQL-I 仍然发生”?我假设您的意思是 SQL 注入?你把Emulate Prepares关掉了吗?我不确定 MySQL 在准备好的语句时实际记录了什么,所以这可能是完全正确的输出。
  • 你能把你的问题说清楚一点吗?对不起,我只是不明白发生了什么与您的期望。

标签: php sql-injection zap


【解决方案1】:

默认情况下,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 的回答中的示例。

【讨论】:

    猜你喜欢
    • 2012-06-28
    • 2015-08-20
    • 2013-02-27
    • 2017-08-24
    • 2020-04-27
    • 2012-08-04
    • 2011-06-26
    • 1970-01-01
    • 2011-10-18
    相关资源
    最近更新 更多