【问题标题】:Using prepared statements? I don't understand it at all [closed]使用准备好的语句?我完全不明白[关闭]
【发布时间】:2013-05-03 12:43:04
【问题描述】:

有人告诉我,这段代码很容易受到 SQL 注入的影响。我如何将其更改为安全?我知道使用准备好的语句是最好的,但我还没有找到一种不会破坏它的方法。

<?php

$con = new mysqli("localhost", "", "", "");
// Check connection
if (mysqli_connect_errno()) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$existsQuery = "select count(*) as count from entry where emailaddress like '" . $_POST[emailaddress] . "'";
$existsResult = mysqli_query($con, $existsQuery);

if ($existsResult->fetch_object()->count > 0) {
    header('Location: index2.php?email=exists');
} else {
    $sql = "INSERT INTO entry (firstname, lastname, emailaddress, favoritesong) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[emailaddress]','$_POST[favoritesong]')";

    if (!mysqli_query($con, $sql)) {
        die('Error: ' . mysqli_error($con));
    }
    echo "1 record added";
}

mysqli_close($con);
?>

【问题讨论】:

  • 老实说,只要给自己找一个好的PDO tutorial 并让它发挥作用。然后返回并将您学到的知识应用到您的代码中。先理解,再应用。同时尝试两者是困难的,并且可能会让人不知所措。
  • 身边还有各种各样的MySQLi教程(如this
  • 永远不要相信客户数据...仅此而已:)

标签: php mysql mysqli


【解决方案1】:

避免 SQL 注入的重要一点是,不要使用字符串连接构建查询。

所以不要像这样构建查询......

$sql = "select count(*) from entry where emailaddress like '" . $_POST[emailaddress] . "'";
$sth = $pdo->prepare($sql);
$sth->execute();

...您将改为使用绑定。通过绑定,?占位符将替换为电子邮件地址,但数据库知道如何引用以及如何转义输入...

$sql = 'select count(*) from entry where emailaddress like ?';
$sth = $pdo->prepare($sql);
$sth->bindParam(1, $_POST[emailaddress], PDO::PARAM_STR);
$sth->execute();

此参数化查询在 PDO 和 SQLi 中有效。 SQL 注入如何工作的演示您可以看到here,只需单击下一个箭头即可填写错误的用户输入。

还有一件事要考虑,绑定将提供一定的 SQL 注入保护,但这不应妨碍您验证用户输入。在您的示例中,这意味着您检查输入是否真的是电子邮件地址,否则只需拒绝用户输入。

【讨论】:

  • 这更好还是本质上是一样的? $emailaddress = $_POST['emailaddress'];$stmt = $db-&gt;prepare('INSERT INTO entry (firstname, lastname, emailaddress, favoritesong) VALUES ( :firstname, :lastname, :emailaddress, :favoritesong)');$stmt-&gt;bindParam(':emailaddress', $emailaddress, PDO::PARAM_STR);
  • @AndrewBrigance - 是的,使用命名参数与示例中的索引 1 相同,它更具可读性。当然,您还需要绑定其他变量(名字、姓氏和喜爱歌曲)。
【解决方案2】:

您需要转义所有传递给 SQL 的变量,尤其是所有 $_POST 和 $_GET。

恕我直言,您可以使用 PDO(引用示例:http://php.net/manual/en/pdo.quote.php)。

希望对你有帮助。

【讨论】:

  • 这是一个问题的答案,如您所见,有一个指向 PHP 手册源的链接。关于设计模式的讨论在这里是一个题外话。
猜你喜欢
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 2014-04-11
  • 2012-06-07
  • 2011-10-01
  • 1970-01-01
  • 2016-02-24
  • 2021-10-13
相关资源
最近更新 更多