PDO param绑定的安全性

时间:2013-05-13 19:50:40

标签: php security pdo

我正在使用PDO的参数化查询来从MySQL数据库中检索具有相当复杂查询的数据。作为这样做的一部分,我使用了类似的代码:

查询:

$query = "SELECT * FROM table WHERE something = :id_$id";
$stmt = $db->prepare($query);

param绑定:

$stmt->bindParam(":id_$id", $id);

我的理解是PDO通过在调用bindParam中“清理”替换字符串来清理参数化输入,但我的问题是: 攻击者是否可以利用上述构造(通过$ id的值)来注入不受欢迎的SQL?

PDO对:id_ $ id进行文本替换,并使用$ id的清理值,因此我认为不包含任何部分:id_ $ id(无论它最终是什么)应该在最后的查询中结束,但我希望得到明确的答案!

编辑:看起来我并不像我应该解释为什么我认为可以安全的事情。当然,我并不认为这是一种良好的方式。

我认为这可能是安全的原因是PDO(如果这是错误的,请纠正我)在替换文本上进行文本替换已清理的bound-param。直观地说,这应该表明替换文本(“:id_ $ id”)可以是任何值,因为当参数放在查询中时它将完全被PDO替换。由于参数替换涉及清理参数的值,而“:id_ $ id”可能是危险的,“$ id”(这是最终查询中出现的)应该是安全的。

这是我的理由,无论如何。我的代码中没有做任何危险的事情,所以这更符合学术兴趣。

3 个答案:

答案 0 :(得分:1)

当然它很脆弱。

但是,使用命名占位符完全是可选的。所以,您根本不必使用它们:

$query = "SELECT * FROM table WHERE something = ?";
$stmt = $db->prepare($query);
$stmt->execute(array($id));

而且,你知道,无论相当复杂的代码都可以简化。

答案 1 :(得分:-1)

pdo会对输入进行清理,您可以在bindValue / bindParam的第三个参数中进一步指定类型。我会避免使用$作为你的令牌的一部分,因为如果在“”:

中它可以被php解释
$query = "SELECT * FROM table WHERE something = :id;";
$stmt = $db->prepare($query);
$stmt->bindParam(":id", $id, PDO::PARAM_INT);

这将确保如果$ id不是int pdo应该引发异常。

即使尝试以这种方式注入sql也会被转义。

答案 2 :(得分:-1)

您应该考虑为$ id使用一组封闭的允许值。我的意思是:

switch ($id) {
  case "value01":
    $param = ":id_01";
    break;

  case "value02":
    $param = ":id_02";
    break;

  default:
    // safe value
    $param = ":id_00";
}

$query = "SELECT * FROM table WHERE something = $param";
$stmt = $db->prepare($query);
$stmt->bindParam("$param", $id);