12

我在这里看到一些人表示使用连接查询mysql_real_escape_string不会(完全)保护您免受 SQL 注入攻击。

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

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

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

这不会保护您免受以下输入的影响:

5 OR 1=1

我认为这是错误使用mysql_real_escape_string而不是缺点,它是为字符串而不是数值设计的。您应该转换为数字类型,或者如果您在清理时要将输入视为字符串,您应该在查询中执行相同操作并在其周围加上引号。

谁能提供一个可以绕过的输入示例,该示例mysql_real_escape_string不依赖于不正确处理数值或忘记mysql_query只能执行一个查询?

编辑:我对它的局限性感兴趣,mysql_real_escape_string而不是将其与替代方案进行比较,我意识到新项目有更好的选择,我对此没有异议。

4

2 回答 2

6

或 mysql_ 扩展的主要缺点mysql_real_escape_string是它比其他更现代的 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 语句中带引号的字符串之外的任何上下文中使用的值,它会被误用,并且可能会或可能不会弄乱结果语法和/或允许某人提交可能启用 SQL 注入攻击的值。的用例mysql_real_escape_string非常狭窄,但很少被正确理解。

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

mysql_set_charset('utf8', $link);

可以这样做:

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

问题是后者绕过了 mysql_ API,它仍然认为您正在使用latin1(或其他)与数据库交谈。现在使用时mysql_real_escape_string,它将假定错误的字符编码和转义字符串,而不是数据库稍后将解释它们。通过运行SET NAMES查询,您在 mysql_ 客户端 API 如何处理字符串与数据库如何解释这些字符串之间产生了分歧。这可用于某些多字节字符串情况下的注入攻击。

如果应用正确mysql_real_escape_string,我知道没有基本的注入漏洞。尽管如此,主要问题还是非常容易错误地应用它,这会带来漏洞。

于 2012-10-04T04:40:27.877 回答
0

好的,所以除了mysql_*被弃用之外,我了解您想了解可能存在的任何可能的解决方法。也许这篇博文和幻灯片可能会揭示其中的一些内容。
但正如这里这个较老的问题所显示的那样,铸造和引用并不能完全证明。有太多的事情会出错,墨菲定律与“永远不要相信网络”这一永远有效的口头禅交织在一起,将会大错特错。

也许这篇文章,但最重要的是,该文章的后续内容可以揭示更多的安全问题。老实说,我知道mysql_real_escape_string即使与类型转换和字符串格式结合使用也不是完全可靠的:

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

没有涵盖所有可能的攻击。
我不是这方面的专家,但我可以告诉你的是清理每一个输入,如果有的话,会给你一种虚假的安全感。大多数时候,您会(最初)知道什么、为什么以及如何防御攻击,但您的同事可能不知道。他们可能会忘记一些事情,并且您的整个系统都会受到损害。

总结:是的,您可能能够防止任何形式的恶意输入进入您的数据库,但它需要的每一个额外操作都会增加风险。在这种情况下,最大的责任(一如既往)是周一早上没有喝第四杯咖啡的开发人员。没有任何代码,无论多么防御和深思熟虑,都可以保护自己免受这个怪物的伤害,这个怪物是一个疲惫的、脾气暴躁的开发人员,对咖啡因和尼古丁冷火了。

于 2012-10-03T07:39:31.053 回答