模拟准备和直接准备呼叫之间的区别?

时间:2013-03-14 23:17:07

标签: php sql pdo prepared-statement sql-injection

数据库是否仍然容易受到使用prepare语句的SQL注入攻击,如下例所示(我正在使用PDO和php版本5.3):

  $unsafe = $_POST['user_input'];

  $stmt = $db->prepare("INSERT INTO table (column) VALUES ('" . $unsafe . "')");

这两个例子中是否有值得一提的差异?

  $stmt = $db->prepare('SELECT * FROM table WHERE name = :name');

  $stmt->execute(array(':name' => $name));

    $stmt = $db->prepare('SELECT * FROM table WHERE name = :name');
    $stmt->bind_param(':name', $name);

    $stmt->execute();

方法执行中可以使用哪些类型的参数?

2 个答案:

答案 0 :(得分:1)

虽然您的实际问题并不完全清楚,但请允许我这样说:

您发布的第一个片段就是出来了。您没有一个有效的参数可以使用已弃用的扩展名(或者已弃用的扩展名),例如mysql_*。忘记所有那些讨厌的mysql_connect电话 看着另外两个片段,我猜你正在使用PDO,它确实支持准备仿真。实际上,它默认情况下模拟准备。但是,如果第三个代码段是mysqli_*代码段,那么问题是什么?除非你运行的是MySQL 3.x,否则你就可以了。

模拟准备和直接准备调用之间的区别在于,仿真可能会发现一些语法错误,而不涉及MySQL服务器,从而提高效率。但是,如果您的MySQL服务器不支持预准备语句,我很确定PDO会为您处理这些问题,所以您应该可以在那里完成。但是,不知道mysqli_*。 考虑到所有事情,无论如何我都赞成第二个片段。它的代码较少,与第三个代码段完全相同,并且允许整齐,易于维护的代码。

关于“方法执行中可以使用哪种类型的参数”的问题,如果PDO它没有参数或数组,你可以查阅文档页面as you can see herebool PDOStatement::execute ([ array $input_parameters ] )
如果是mysqli_execute,则取决于您使用OO或程序样式as shown in the docs
OO的bool mysqli_stmt::execute ( void ) 程序风格bool mysqli_stmt_execute ( mysqli_stmt $stmt )

答案 1 :(得分:0)

  

数据库是否仍然容易受到使用prepare语句的SQL注入攻击,如下例

为什么呢?当然。因为在这个例子中没有实际使用的预备语句。

  

模拟准备和直接准备电话之间的区别?

在安全方面没有区别 - 两种方式都是安全的 但是,可能会有下面描述的不便

Errr ......我刚想到你可能对模拟准备的内容有错误的认识。
你问题中的第一个代码片段根本不是一个准备好的陈述,既不是模仿也不是自然 - 而是旧的好的推断,背后有所有的危险。
虽然模拟准备仅代表PDO操作查询的方式,但解释here

  

方法执行中可以使用哪些类型的参数?

这很明显 - 所有参数默认都被视为字符串

因此,您的查询无论如何都是无懈可击的,但如果仿真处于ON状态可能会有一些不便 - 如果LIMIT子句中有占位符,则必须显式绑定参数,不将它们传递给execute,设置INT类型为它们。
但是如果禁用仿真,mysql可以对所有参数进行排序,你可以将数组一直发送到execute()