为了账号安全,请及时绑定邮箱和手机立即绑定

mysql_real_escape_string的缺点?

/ 猿问

mysql_real_escape_string的缺点?

45度呼吸 2019-12-05 16:11:41

我在这里看到一些人指出,使用串联查询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对替代品的局限性很感兴趣,并且没有将其与替代品进行比较,我意识到新项目有更好的选择,并且对此没有争议。


查看完整描述

3 回答

?
ibeautiful

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语句中带引号的字符串之外的任何上下文中使用的值,它将被错误地使用,并且可能会或可能不会干扰所得的语法和/或允许某些人提交可能启用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我知道,如果正确应用,则没有基本的注入漏洞。同样,主要问题是,错误地应用它非常容易,这会带来漏洞。


查看完整回答
反对 2019-12-05
?
临摹微笑

好的,除了mysql_*被弃用之外,我了解您想知道可能存在的任何可能的解决方法。也许这篇博客文章和幻灯片可能会揭示其中的一些内容。

但是,正如这里的较早的问题所显示的,强制转换和引用并不能完全证明这一点。有太多事情可能出错,而墨菲定律与那句永不止息的口号“永不信任网络”缠绕在一起,将大错特错。


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


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

无法涵盖所有可能的攻击。

我不是这方面的专家,但是我可以告诉您的是对每个输入进行消毒,如果有的话,将给您带来虚假的安全感。大多数时候,您会(最初)知道如何以及为什么以及如何防御攻击,但是您的同事却可能不知道。他们可能会忘记某些事情,并且整个系统都将受到损害。


总结:是的,您也许能够阻止任何形式的恶意输入进入您的数据库,但是它需要执行的每一项其他操作都会带来额外的风险。在那种情况下,最大的责任(一如既往)是周一早上没有喝过第四杯咖啡的开发商。任何代码,无论如何防御和深思熟虑,都无法保护自己免受怪物的侵害,因为怪物是脾气暴躁,脾气暴躁,对咖啡因和尼古丁无视的火鸡。


查看完整回答
反对 2019-12-05
?
千万里不及你

本身,我发布的代码片段无法被AFAIK所利用,但会产生错误,并且在探测漏洞时会产生恶意,例如恶意调用ppl。您还很有可能在WHERE子句中使用1个以上的参数,每个参数都需要三个附加操作(字符串格式,类型强制转换和转义调用),因此此方法容易出错(进行强制转换)或占位符错误,则不再安全)。在我也链接的问题中,排序规则的意义也提出了,我的摘录根本没有解决 

查看完整回答
反对 2019-12-05

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信