一尘不染

mysql_real_escape_string的缺点?

php

我在这里看到一些人指出,使用串联查询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


阅读 262

收藏
2020-05-26

共1个答案

一尘不染

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我知道, 如果正确应用 没有基本的注入漏洞
同样,主要问题是,错误地应用它非常容易,这会带来漏洞。

2020-05-26