mysql_real_escape_string 失败且需要准备语句的具体示例
我一直在使用 mysql_real_escape_string 和其他函数来清理我的输入,并且最近读到准备好的语句是真正安全的唯一方法。然而,我不愿意使用它们有两个原因:我不想重写代码,并且我了解到使用它们会对性能产生影响(在此应用程序中广泛使用查询)。
因此,我正在寻找一个最近的具体示例,说明 mysql_real_escape_string 在查询中失败,解决方案是使用准备好的语句(即,无法进一步清理输入并保证其安全)。
我问这个问题是因为我能找到的唯一符合上述标准的例子是前一段时间的,并且已经在更新版本的 php 中进行了修补。
I've been sanitising my inputs using mysql_real_escape_string amongst other functions and have recently read that Prepared Statements are the only way to be truly secure. However I am reluctant to use these for two reasons: I don't want to rewrite code and I read that using them can have an impact on performance (queries are used extensively in this application).
So I am looking for a recent, concrete example of where mysql_real_escape_string fails in a query and the resolution is to use Prepared Statements (i.e. there is no way to further sanitise the input and guarantee it's safe).
I ask this because the only example I could find which met the above criteria were from some time ago and have since been patched out in more up to date versions of php.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从该函数的 PHP 文档 (http://php.net/mysql_real_escape_string) 中,它显示“mysql_real_escape_string( ) 调用 MySQL 的库函数 mysql_real_escape_string,该函数在以下字符前面添加反斜杠:\x00、\n、\r、\、'、 “和\x1a。”
因此,它的用处取决于上下文。因此,举例来说,如果您遇到以下情况:
嗯,那将是非常愚蠢的。因为如果字符串是
0 或 9=9
,那么它不包含函数转义的任何字符。然而,当注入 $query 文字时,它会产生:这将返回
users
表中的所有行......这可能不是程序员的意图。因此,总而言之,如果用户输入由 mysql_real_escape_string() 处理,但在整数或其他数字数据类型的上下文中使用,那么它将无法提供足够的保护。
使用准备好的语句,您可以确保每个值不仅被转义,而且被验证为正确的数据类型。
在上面的示例中,处理该问题的最安全方法是使用 intval() 函数而不是 mysql_real_escape_string() 函数。
希望这是有道理的。
From the PHP Documentation for the function (http://php.net/mysql_real_escape_string), it says "mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a."
Thus, it's usefulness depends on the context. So, for example, if you had the following scenario:
Well, that would be pretty stupid. Because if the string was
0 or 9=9
, then that does not contain any of the characters which the function escapes. However, when injected into the $query literal, it produces :This would return all rows in the
users
table...... Which is probably not the intention of the programmer.So, to sumarise, if the user input is handled by mysql_real_escape_string() but made use of in the context of an integer or other numeric data type, then it would fail to provide sufficient protection.
With prepared statements, you can ensure that each value is not only escaped, but validated to be the correct data type.
In the example above, the safest way to have handled that would have been to use the intval() function instead of the mysql_real_escape_string() function.
Hope that made sense.
mysql_real_escape_string()
的全部目的是 100% 保证用它转义的数据中不会有 SQL 注入。它远远优于addslashes()
,因为它考虑了当前连接的字符编码。如果该功能在实际实现中不存在严重错误,那么可以安全使用。
人们不希望您使用它的原因是您可能忘记在某个地方或另一个地方,从而打开安全漏洞。准备好的语句更难搞砸,但是如果正确转义数据,构建自己的 SQL 并没有什么根本性的错误。
编辑:
请注意在建立连接后可能会更改连接的字符集,从而导致与
mysql_real_escape_string
不同步。我还没有确认情况仍然如此。另请注意,
mysql_real_escape_string()
必须是在将数据与 SQL 连接之前对数据执行的最后一个操作。另外,不要忘记引号!例如。
AND name = "' .mysql_real_escape_string($name) . '"
The entire purpose of
mysql_real_escape_string()
is to 100% guarantee that there can be no SQL injection in the data you escape with it. It is far superior toaddslashes()
because it takes into account the current connection's character encoding.Provided there is not a critical bug in the actual implementation of this function, then it is safe to use.
The reason people do not want you to use it is that you might forget at some place or another, opening up a security hole. Prepared statements are harder to screw up, but there is nothing fundamentally wrong with constructing your own SQL if you properly escape the data.
Edit:
Please take note of the potential ability to change the character set of the connection after it is established, and therefore go out of sync with
mysql_real_escape_string
. I have not confirmed this is still the case.Also note that
mysql_real_escape_string()
must be the last operation performed on the data prior to concatenating it with the SQL.Also, don't forget the quotes! Eg.
AND name = "' . mysql_real_escape_string($name) . '"
mysql_real_escape_string 100% 可靠。这就是您随后对转义数据所做的操作失败的原因。
例如,
m_r_e_s 将完美地完成其工作,然后您可能会通过之后再次摆弄字符串来撤消所有操作。
m_r_e_s 应该是在 SQL 查询中使用字符串之前对字符串执行的最后一个操作。
mysql_real_escape_string is 100% reliable. It's what you DO with the the escaped data aftewards that fails.
e.g.
m_r_e_s will have done its job perfectly, and then you've potentially undone everything by fiddling with the string again afterwards.
m_r_e_s should be the VERY last operation performed on the string before it's used in an SQL query.