我知道你们中的一些人可能会回答这个问题,但我的问题是从你们和你们的回答中提出的。我正在阅读过去两个小时的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();
4条答案
按热度按时间qzwqbdag1#
二者都准备好的语句将保护您不受SQL注入的影响,前提是您以正确的方式使用它们。例如,如果您仍然在为表/列名称插入变量,那么仅仅“使用”准备好的语句就无济于事。
ss2ws0br2#
事先准备好的陈述没有。绑定参数保护语句(而不是整个数据库),只要所有不受信任的数据都是通过参数传递的,而不是插入到语句中。当人们使用预先准备好的语句时,他们几乎总是使用绑定参数,因此这两个名称经常被混淆。
1.准备报表
1.使用变量作为附加参数运行语句
mysql_real_escape_string
几乎总是完成这项工作,但由于它向流程添加了额外的步骤,因此更容易出现人为错误。1.转义每个变量
1.将变量连接到SQL语句中
1.运行语句
ulmd4ohb3#
这是一个很好的讨论。您的问题假设有一种技术可以“保护您的数据库”。事实上,没有一种技术最适合所有情况。因此,你需要学会在不同的情况下使用多种解决方案。
请参阅我的演示文稿SQL Injection Myths and Fallacies,其中我详细介绍了防御SQL注入所需的一切。
我还在我的书SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming中介绍了SQL注入。
9lowa7mx4#
在某些情况下,无法使用准备好的语句。例如,当您必须动态生成
IN()
子句的内容时,如果您动态选择了逗号分隔的值进入IN()
,则无法执行WHERE col IN (?)
。此外,如果您需要在SELECT
语句中动态生成列列表,则必须通过构建SQL字符串来执行。底线是,两者都有各自的位置。对于预定查询或必须多次执行的查询,准备好的语句非常好。转义动态SQL在以下情况下非常出色:1)您必须具有最大的灵活性;2)您不要忘记转义所有输入。