应该使用哪种 PDO 绑定方法来提高安全性?

Posted

技术标签:

【中文标题】应该使用哪种 PDO 绑定方法来提高安全性?【英文标题】:Which PDO bind approach should be used for greater security? 【发布时间】:2015-03-20 14:38:35 【问题描述】:

我知道在 php 中使用 PDO 更新 mysql 数据库记录的两种方法。请有人解释一下我应该使用哪个以获得更好的安全性和区别,我有点困惑。

方法一:

$user = "root";
$pass = "";
$dbh = new PDO('mysql:host=somehost;dbname=somedb', $user, $pass);
$sql = "UPDATE coupons SET 
coupon_code = :coupon_code, 
valid_from = :valid_from, 
valid_to = :valid_to,  
discount_percentage = :discount_percentage,  
discount_amount = :discount_amount,  
calculationType = :calculationType,  
limit = :limit  
WHERE coupon_code = :coupon";
$stmt = $dbh->prepare($sql);                                  
$stmt->bindParam(':coupon_code', $_POST['coupon_code'], PDO::PARAM_STR);       
$stmt->bindParam(':valid_from', $_POST['$valid_from'], PDO::PARAM_STR);    
$stmt->bindParam(':valid_to', $_POST['valid_to'], PDO::PARAM_STR);
$stmt->bindParam(':discount_percentage', $_POST['discount_percentage'], PDO::PARAM_STR); 
$stmt->bindParam(':discount_amount', $_POST['discount_amount'], PDO::PARAM_STR);   
$stmt->bindParam(':calculationType', $_POST['calculationType'], PDO::PARAM_STR);   
$stmt->bindParam(':limit', $_POST['limit'], PDO::PARAM_STR);   
$stmt->bindParam(':coupon', $_POST['coupon_code'], PDO::PARAM_STR);   
$stmt->execute();

方法二:

$dbtype="somedbtype";
$dbhost="somehost";
$dbname="somedb";
$dbuser="someuser";
$dbpass= "somepass";
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$title = 'PHP Pattern';
$author = 'Imanda';
$id = 3;
$sql = "UPDATE books 
SET title=?, author=?
WHERE id=?";
$q = $conn->prepare($sql);
$q->execute(array($title,$author,$id));

据我所知,方法二并没有绑定数据,而是直接将其作为数组类型插入到查询中。这是否会使脚本更容易受到 SQL 注入或其他安全风险的影响?

【问题讨论】:

【参考方案1】:

两者之间的唯一区别是,如果您将数组传递给execute函数而不是自己调用bindParam,它会自动将所有参数视为PDO::PARAM_STR,而在自己调用bindParam时,您可以将它们绑定为整数等。

来自docs:

输入参数

包含与正在执行的 SQL 语句中的绑定参数一样多的元素的值数组。所有值都被视为 PDO::PARAM_STR。

您还可以从那里的示例中看到,在将数组传递给execute 函数时,您可以使用命名参数(例如:limit)。您不必只输入?。在这种情况下,你给数组一个键:

$sth->execute(array(':calories' => $calories, ':colour' => $colour));

【讨论】:

非常有用,谢谢!我正在将我所有的 mysqli 更新到 PDO 以进行内务管理,并想知道其中的区别。谢谢:D【参考方案2】:

这主要是一个偏好问题。两者都可以保护您免受注射。

虽然我认为使用 bind() 强制数据类型要容易得多,而使用 execute(array()) 将使用字符串。

【讨论】:

以上是关于应该使用哪种 PDO 绑定方法来提高安全性?的主要内容,如果未能解决你的问题,请参考以下文章

安全问题:Mysqli vs PDO [重复]

使用password_hash密码默认注册登录

这个 PDO 代码对 SQL 注入是不是足够安全? [复制]

MySQL IN 语句的 PDO 绑定值 [重复]

PHP PDO 连接到具有集成安全性的 SQL Server?

php 使用CRUD方法的简单而安全的PHP PDO数据库包装器......