PHP 防止 SQL 注入
Posted
技术标签:
【中文标题】PHP 防止 SQL 注入【英文标题】:PHP Prevent SQL Injection 【发布时间】:2018-03-23 01:46:57 【问题描述】:我正在尝试使用带有 PDO 的 php 来防止 SQL 注入。我用这个作为参考。 http://wiki.hashphp.org/PDO_Tutorial_for_mysql_Developers 。我的代码没有给我任何错误,但是输入的值都是空的。
我试图插入的值是 not null。我知道这一点,因为我已经将它们呼应出来:
echo "\nDate: ".$date." Name: ".$name." mail: ".$mail."Comment: ".$comment." website: ".$website;
$sql = "INSERT post SET timeDate = :timeDate and name = :name and mail = :mail and comment = :comment and website = :website";
$stmt = $db->prepare($sql);
$stmt->bindParam(":timeDate", $date);
$stmt->bindParam(":name", $name);
$stmt->bindParam(":mail", $mail);
$stmt->bindParam(":comment", $comment);
$stmt->bindParam(":website", $website);
$stmt->execute();
【问题讨论】:
顺便说一句,您实际上并不需要如此长而曲折的代码,实际上两行就足够了:PDO Examples: UPDATE query using PDO$sql = "INSERT post SET name=?, mail=?";
$db->prepare($sql)->execute([$name, $mail]);
但是这种注射安全吗?
是的,但您还需要添加其他字段
其他字段如?
在您的查询中
【参考方案1】:
不要在作业之间使用AND
——使用逗号。
$sql = "INSERT post
SET timeDate = :timeDate,
name = :name,
mail = :mail,
comment = :comment,
website = :website";
您在条款之间使用AND
的语句没有错误,因为该语句实际上是有效的。它只是没有按照你的想法做。
就好像你这样做了:
SET timeDate = (:timeDate and name = :name and mail = :mail and comment = :comment and website = :website")
这仅将 timeDate 设置为一个长布尔表达式的结果。
其他列没有被分配任何东西,它们只是与参数化值进行比较。由于这是您尚未插入的新行,所有其他列自然为 NULL,因此比较将为 NULL。因此AND
-ing 它们在一起将是 NULL,这是将分配给您的 timeDate
列的最终值。
其他列在此语句中没有赋值,它们的默认值大概是NULL。
这是一个奇怪而无用的说法,但严格来说,这不是错误。
我还鼓励您更简单地使用 PDO。您可以将数组传递给execute()
,而不是使用bindParam()
。这与您对每个参数执行 bindValue()
的效果相同。您可以使用命名参数或位置参数来执行此操作。
$stmt = $db->prepare($sql);
$stmt->execute([
"timeDate" => $date,
"name" => $name,
"mail" => $mail,
"comment" => $comment,
"website" => $website]);
如果您已经将参数值存储在数组中,这将特别方便。
对 SQL 注入的保护与使用 bindParam()
一样好。
【讨论】:
以上是关于PHP 防止 SQL 注入的主要内容,如果未能解决你的问题,请参考以下文章