使用绑定参数的PHP MySQLi准备的查询是否安全?

使用绑定参数的PHP MySQLi准备的查询是否安全?,php,mysqli,prepared-statement,Php,Mysqli,Prepared Statement,从历史上看,我一直使用 mysql_real_escape_string() 对于从最终接触数据库的用户派生的所有输入 现在我已经完全转换到MySQLi,并且使用带绑定参数的准备好的查询,我是否有效地消除了SQL注入攻击的可能性 我说我不再需要你了,对吗 mysql_real_escape_string()? 这是我的理解,也是我的一个项目的基础: 这并不是我想弄错的,因为现在我已经发布了它,它也可能影响其他人 所有用户提供的输入现在都将以绑定方式结束。 准备阶段提供的查询是静态的。是。使

从历史上看,我一直使用

mysql_real_escape_string()
对于从最终接触数据库的用户派生的所有输入

现在我已经完全转换到MySQLi,并且使用带绑定参数的准备好的查询,我是否有效地消除了SQL注入攻击的可能性

我说我不再需要你了,对吗

mysql_real_escape_string()?
这是我的理解,也是我的一个项目的基础:

这并不是我想弄错的,因为现在我已经发布了它,它也可能影响其他人

所有用户提供的输入现在都将以绑定方式结束。

准备阶段提供的查询是静态的。

是。使用准备好的查询将转义参数。

将参数绑定到准备好的语句时,它会自动转义数据,因此在发送之前不应转义。双重逃跑通常是件坏事。至少,它会在以后产生带有额外转义字符的丑陋结果。

它不是那么简单。您可以使用绑定参数,而不只是将应用程序变量插入SQL表达式中,以代替文字值:

但是,如果除了文本值之外,还需要使查询的一部分成为动态的,该怎么办

$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe

$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work!
参数将始终被解释为值,而不是列标识符。您可以使用
按“分数”排序的查询
,这不同于
按分数排序的查询
,使用参数将被解释为前者——一个常量字符串
'score'
,而不是名为
score
的列中的值

因此,在很多情况下,您必须使用动态SQL并在查询中插入应用程序变量以获得所需的结果。在这种情况下,查询参数帮不了你。为了防止SQL注入缺陷,您仍然必须保持警惕并进行代码防御

没有任何框架或数据访问库可以为您完成这项工作。您可以始终构造包含SQL注入缺陷的SQL查询字符串,并在数据访问库看到SQL查询之前执行此操作。那么,它如何知道什么是故意的,什么是缺陷呢

以下是实现安全SQL查询的方法:

  • 过滤输入。跟踪插入SQL查询的任何变量数据。使用输入删除非法字符。例如,如果需要整数,请确保输入被约束为整数

  • 转义输出。此上下文中的输出可以是发送到数据库服务器的SQL查询。您知道可以对值使用SQL查询参数,但是列名呢?标识符需要一个转义/引用函数,就像旧的
    mysql\u real\u escape\u string()
    用于字符串值一样

  • 代码审查。让某人成为你的第二双眼睛,检查你的SQL代码,帮助你找出你忽略使用上述两种技术的地方


谢谢。只是想确保我没有遗漏一些明显的东西。我倾向于这样做,是的。注意到你不能按订单吗?带参数的位。回答得好,我投了反对票?下面,你应该描述一下为什么你认为这个答案不令人满意。也许我可以改进它。
$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe

$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work!