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 注入的主要内容,如果未能解决你的问题,请参考以下文章

php如何防止sql注入?

php如何防止sql注入

php如何防止sql注入

php中防止SQL注入的方法

PHP 防止 SQL 注入

留言板防灌水功能应该怎么做?怎么防止sql注入?用PHP编写