首先,我知道人们想要使用存储过程以便他们重用查询并处理转义。然而,我看到很多开发者说 mysqli_real_escape_string
不能 100% 防止 SQL 注入(inject)。有人可以提供这方面的例子吗?
根据我对这个主题的有限了解,我会说 mysqli_real_escape_string
对于字符串总是没问题,但对于数值你可能会被抓到,除非你检查数字是一个 int、float、double 等。
编辑:我忘了添加一些关键的东西:假设字符集是 UTF8 并且相应地调用了 mysqli_set_charset。我见过的唯一注入(inject)依赖于一些字符集(没有一个是 UTF8)。
只要您使用 mysqli_set_charset()
设置客户端编码,并且 mysqli_real_escape_string()
用于格式化仅字符串,它绝对安全。
但是,如果您的问题暗示在应用程序代码中正确使用此函数,而不是在后台处理基于占位符的查询或至少以 PDO 的 quote()
形式 -像函数(它会立即转义 和 引用)它是注入(inject)的直接方式。
问题不是函数本身,而是使用方式:
- 因为它只完成所需格式的部分,所以很容易忘记另一部分并陷入麻烦
- 甚至它很容易被误用,格式化的不是字符串,而是另一种完全不会从转义中获益的文字。
- 其次,当它在应用程序代码中正确使用时,它的使用会变得不一致或偶尔出现,因为没有办法强制开发人员正确无误地格式化每个文字。这又可能导致不准确和注入(inject)。
这就是为什么您必须始终使用占位符来表示查询中的数据(而 mysqli_real_escape_string 可以用来处理这个占位符)