为什么这个易受攻击的PDO工作而不是准备好的声明?

时间:2015-08-28 08:20:58

标签: php mysql pdo sql-injection

我的PDO查询只有一种方式返回我想要的结果,但是正确的预处理语句只给出了列名。

这将返回列名而不是查询行:

$queryPrice = "SELECT :zone FROM express WHERE kg >= :kg LIMIT 1";
$stmt = $conn->prepare($queryPrice);
$stmt->bindParam(':zone', $zone, PDO::PARAM_STR);
$stmt->bindParam(':kg', $_SESSION['weight'], PDO::PARAM_STR);
$stmt->execute();
$price = $stmt->fetchColumn();

这样可行,但容易受到注射:

$queryPrice = "SELECT $zone FROM express WHERE kg >= :kg LIMIT 1";
$stmt = $conn->prepare($queryPrice);
$stmt->bindParam(':kg', $_SESSION['weight'], PDO::PARAM_STR);
$stmt->execute();
$price = $stmt->fetchColumn();

为什么没有为列名准备声明?

有没有一种安全的方法可以达到预期的效果?

1 个答案:

答案 0 :(得分:1)

关于第二个想法,您的问题似乎是由糟糕的数据库设计引起的。

不必将区域作为表中的列,而是必须将它们作为另一个表中的单个列中的数据。事实证明,您试图以只需要解决数据的方式来处理列名。

您重新组织了表格,只为区域留下了一列,例如name。并且您可以使用类似

的查询选择您的区域
SELECT name FROM zones WHERE kg > :kg