mysql_real_escape_string的缺点?

我已经看到这里有几个人声明,使用mysql_real_escape_string连接查询不会保护你(完全)SQL注入攻击。

但是,我还没有看到一个input示例,说明了mysql_real_escape_string不会保护您的攻击。 大多数示例忘记mysql_query仅限于一个查询,并且不正确地使用mysql_real_escape_string

我能想到的唯一例子如下:

 mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input)); 

这不会保护您免受以下input:

 5 OR 1=1 

我会看到这是mysql_real_escape_string不正确使用,而不是一个缺点,它是专为string而不是数值。 您应该转换为数字types,或者如果要在input消息时将input视为string,则应在查询中执行相同的操作,并在其周围引号。

任何人都可以提供一个input的例子, mysql_real_escape_string不依赖不正确的数值处理,或忘记mysql_query只能执行一个查询吗?

编辑:我感兴趣的是mysql_real_escape_string的限制,而不是比较它的替代品,我知道有新项目更好的select,而不是争议。

mysql_real_escape_string或者mysql_扩展的主要缺点是比其他更现代化的API(特别是预处理语句)更难正确应用。 mysql_real_escape_string应该只用于一种情况:转义文本内容,用作SQL语句中引号之间的值。 例如:

 $value = mysql_real_escape_string($value, $link); $sql = "... `foo` = '$value' ..."; ^^^^^^ 

mysql_real_escape_string确保上面的上下文中的$value不会搞乱SQL语法。 这不符合你的想法:

 $sql = "... `foo` = $value ..."; 

或在这里:

 $sql = "... `$value` ..."; 

或在这里:

 $sql = mysql_real_escape_string("... `foo` = '$value' ..."); 

如果应用于在SQL语句中除引号string以外的任何上下文中使用的值,则会被误用,并且可能会或可能不会弄乱所产生的语法和/或允许某人提交可能导致SQL注入攻击的值。 mysql_real_escape_string的用例非常狭窄,但很less被正确理解。

使用mysql_real_escape_string让自己进入热水的另一种方法是使用错误的方法设置数据库连接编码。 你应该做这个:

 mysql_set_charset('utf8', $link); 

可以这样做:

 mysql_query("SET NAMES 'utf8'", $link); 

问题是后者绕过了mysql_API,它仍然认为你正在使用latin1 (或其他)与数据库交谈。 现在,当使用mysql_real_escape_string ,它将采用错误的字符编码和转义string,而数据库稍后将解释它们。 通过运行SET NAMES查询,您已经在mysql_客户端API处理string的方式和数据库将如何解释这些string之间创build了一条裂缝。 这可以用于某些多字节string情况下的注入攻击。

mysql_real_escape_string中没有基本的注入漏洞,我知道它是否正确应用。 然而,主要的问题是,错误地应用它是非常容易的,这就造成了漏洞。

好的,除了mysql_*被弃用,我明白你想知道可能存在的任何可能的解决方法。 也许这个博客文章和幻灯片可能会揭示其中的一些。
但是,正如这个老问题所显示的那样,铸造和引用并不完全certificate。 只有很多事情是错的 ,而墨菲定律与这个永远不会相信networking的有效口头禅结合在一起,将会犯下可怕的错误。

也许这篇文章 ,但最重要的是, 这篇文章 的后续可以揭示更多的安全问题。 说实话,我知道mysql_real_escape_string是不是全面的,即使在与types转换和string格式的组合:

 printf('WHERE id = \'%d\'',(int)mysql_real_escape_string($_REQUEST['id'])); 

不包括每一个可能的攻击。
我不是这方面的专家,但我可以告诉你的是对每一个input进行消毒,如果有的话,会给你一个错误的安全感。 大多数情况下,你会知道(最初)什么,为什么,如何防范攻击,但你的同事可能不知道。 他们可能会忘记一些东西,而且整个系统都被破坏了。

总结:是的,您可能能够阻止任何forms的恶意input到您的数据库,但它需要的每一个额外的行动是一个额外的风险。 在这种情况下,最大的责任(一如既往)是一个星期一早上没有的开发者是第四杯咖啡。 没有代码,无论是多么防守和经过深思熟虑,都可以保护自己免受脾气暴躁的疲倦的开发者,用咖啡因和尼古丁来冷却火鸡。