PHP:使用准备好的语句进行注入保护

Posted

技术标签:

【中文标题】PHP:使用准备好的语句进行注入保护【英文标题】:PHP: Injection protection using prepared statements 【发布时间】:2010-12-19 10:52:03 【问题描述】:

我熟悉使用 php 执行 mysql 查询。但是,我一直在使用 reg exps 作为对注入攻击的保护。在阅读了关于 SO 的几个问题/答案后,我决定改为选择准备好的陈述。

有两种选择(如果有更多请告诉我):

    mysqli prepared statements PDO prepared staments

问题 1

我正在尝试理解链接页面上给出的代码示例。

对于 mysqli,示例 #1:

if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) 
    $stmt->bind_param("s", $city);

"s" 参数有什么作用? 如果我需要超过 1 个参数,我该怎么做?

对于 PDO,示例 #1:

$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));

PDO::ATTR_CURSORPDO::CURSOR_FWDONLY 这里的目的是什么?

问题 2

你会推荐哪一个,mysqli 或 PDO?利弊?

【问题讨论】:

【参考方案1】:

s 表示$city 应该是一个字符串

PDO::ATTR_CURSOR 部分是您要传递给 PDO 的设置的名称。值 PDO::CURSOR_FWDONLY(这是默认值,因此您不需要指定 if)意味着对于您对 PDOStatement::fetch() 的每次调用,您将获得结果集中的下一行。替代选项是PDO::CURSOR_SCROLL - 但除非您明确知道您需要这个(并且您的数据库支持它),否则您应该将其保留为默认值。

【讨论】:

【参考方案2】:

问题 1

s 参数将 ":" 绑定到 $city 的任何值。所以如果你的sql是“SELECT District FROM City WHERE Name = s”,那么你执行的查询就是“SELECT District FROM City Where Name = $city”。

要绑定更多参数,只需为每个参数调用bindParam。您还可以将数组传递给 PDOStatement::execute。

问题 2

由于我使用一些不同的数据库(mysql 和 sqllite),我更喜欢使用 PDO。有关此主题的更多信息,请参阅mysqli or PDO - what are the pros and cons?。

【讨论】:

以上是关于PHP:使用准备好的语句进行注入保护的主要内容,如果未能解决你的问题,请参考以下文章

PHP:使用准备好的语句并防止 SQL 注入与逃逸

创建 MySQL 准备好的语句

PHP PDO:保护动态标识符免受 SQL 注入

选择查询的准备语句问题

多个 MySQLi 准备语句和漏洞(评价我的代码)

PDO 准备好的语句,正确使用了吗?