准备语句是否保护数据库?

3lxsmp7m  于 2022-10-22  发布在  PHP
关注(0)|答案(4)|浏览(109)

我知道你们中的一些人可能会回答这个问题,但我的问题是从你们和你们的回答中提出的。我正在阅读过去两个小时的SQL注入问题和答案,以及如何保护数据库。我看到的大量网页和教程也是如此。
我发现,一半的人声称准备声明确实保护了你的数据库,另外50人则声称没有。
另一方面,我读到mysql_real_escape_string完成了这项工作,而其他人则说它不是。
我的问题是该相信谁?
此外,这是正确的准备声明吗?

$stmt = $dbh->prepare("SELECT phpro_user_id, phpro_username, phpro_password FROM phpro_users 
                    WHERE phpro_username = :phpro_username AND phpro_password = :phpro_password");

        /***bind the parameters***/
        $stmt->bindParam(':phpro_username', $phpro_username, PDO::PARAM_STR);
        $stmt->bindParam(':phpro_password', $phpro_password, PDO::PARAM_STR, 40);

        /***execute the prepared statement***/
        $stmt->execute();
qzwqbdag

qzwqbdag1#

二者都准备好的语句将保护您不受SQL注入的影响,前提是您以正确的方式使用它们。例如,如果您仍然在为表/列名称插入变量,那么仅仅“使用”准备好的语句就无济于事。

$stmt = "SELECT * FROM $table WHERE $column = ?"; //not good...
ss2ws0br

ss2ws0br2#

事先准备好的陈述没有。绑定参数保护语句(而不是整个数据库),只要所有不受信任的数据都是通过参数传递的,而不是插入到语句中。当人们使用预先准备好的语句时,他们几乎总是使用绑定参数,因此这两个名称经常被混淆。
1.准备报表
1.使用变量作为附加参数运行语句
mysql_real_escape_string几乎总是完成这项工作,但由于它向流程添加了额外的步骤,因此更容易出现人为错误。
1.转义每个变量
1.将变量连接到SQL语句中
1.运行语句

ulmd4ohb

ulmd4ohb3#

这是一个很好的讨论。您的问题假设有一种技术可以“保护您的数据库”。事实上,没有一种技术最适合所有情况。因此,你需要学会在不同的情况下使用多种解决方案。

  • 转义文字值
  • 准备好的查询中的参数占位符
  • 白名单Map

请参阅我的演示文稿SQL Injection Myths and Fallacies,其中我详细介绍了防御SQL注入所需的一切。
我还在我的书SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming中介绍了SQL注入。

9lowa7mx

9lowa7mx4#

在某些情况下,无法使用准备好的语句。例如,当您必须动态生成IN()子句的内容时,如果您动态选择了逗号分隔的值进入IN(),则无法执行WHERE col IN (?)。此外,如果您需要在SELECT语句中动态生成列列表,则必须通过构建SQL字符串来执行。
底线是,两者都有各自的位置。对于预定查询或必须多次执行的查询,准备好的语句非常好。转义动态SQL在以下情况下非常出色:1)您必须具有最大的灵活性;2)您不要忘记转义所有输入

相关问题