【问题标题】:Should we always use prepared statements in MySQL and php or when to use these?我们应该总是在 MySQL 和 php 中使用准备好的语句,还是什么时候使用它们?
【发布时间】:2018-12-03 13:44:37
【问题描述】:

我读了很多文章,说使用准备好的语句非常安全,并且可以很好地防止 SQL 注入。我在没有使用准备好的语句的情况下建立了一些网站。但是在阅读了所有这些文章之后,我正在考虑使用准备好的语句来更改整个代码。

我的问题

是否有必要总是使用准备好的语句?或者是否有任何情况下正常的语句足以胜过准备好的语句?

【问题讨论】:

标签: php mysqli sql-injection


【解决方案1】:

刚发现你的问题,我想起了我过去的美好时光。我也发现很难实现准备好的语句,因为乍一看,没有它感觉很容易编码。然后在另一次,我使用 PHP 制作了一个让我感到自豪的登录系统。虽然完全从头开始制作,但感觉很棒。但是,我犯了一个错误,没有使用它们,然后我检查了谷歌如何绕过登录系统。第一个技巧让我头疼,因为我现在可以在不知道用户名或密码的情况下登录我的网页,只需使用一些字符,如'-',然后我就进入了我的网页。所以我一路返回并使用参数化查询来保护它,现在它是安全的。既然你我都是初学者,这些东西肯定会让我们头疼。此外,仅当您从用户输入中接受某些内容时,您才需要使用它们。否则你很高兴。只需四处寻找其他漏洞,例如 XSS 等。这些也很危险。祝你好运

【讨论】:

    【解决方案2】:

    如果您有一个完全硬编码的 SQL 查询,并且在 SQL 中不需要 PHP 变量,那么非准备语句就足够了。

    这是一个例子:

    $result = $mysqli->query("SELECT * FROM mytable WHERE updated_at > NOW() - INTERVAL 7 DAY");
    

    查询是独立的。它只是一个固定的字符串,完全由您的应用程序控制。任何不受信任的内容都不会影响查询。

    如果您的查询需要一些可变部分,则使用查询参数,如下所示:

    $stmt = $mysqli->prepare("SELECT * FROM mytable WHERE updated_at > NOW() - INTERVAL ? DAY");
    $stmt->bind_param("i", $number_of_days);
    $stmt->execute();
    

    查询参数的重点是将可能不受信任的内容与 SQL 解析步骤分开。通过使用参数,绑定变量的值直到 SQL 被解析后才与查询结合。因此,绑定参数无法影响查询的逻辑——该参数将被限制为在查询中充当单个标量值。

    【讨论】:

    • 你也可以使用字符串转义(例如mysqli_real_escape_string)而不是预先准备好的语句,但是它可能会让你一头雾水,然后你就有麻烦了;此外,转义的实现可能很糟糕(这就是为什么首先有一个名为mysqli_real_escape_string 的函数的原因)。正如上面 Bill 所示,养成始终使用参数化语句的习惯是一个非常好的习惯。
    • 这个。如果你认为使用它太难了,或者代码太多而无法继续移动,或者记住细节等等,那么编写一个包装函数或类来完成这一切,只需向它传递一个查询字符串和参数数组,然后根据需要取回状态和/或结果集。 mysql_ 函数已经死了,当你修复旧代码时,真的修复它!
    猜你喜欢
    • 2014-09-19
    • 2011-09-30
    • 2013-03-25
    • 1970-01-01
    • 2021-10-02
    • 2011-03-18
    相关资源
    最近更新 更多