mysql_real_escape_string的缺点? [英] Shortcomings of mysql_real_escape_string?
问题描述
我在这里看到一些人指出,使用mysql_real_escape_string
并置查询并不能(完全)保护您免受SQL注入攻击.
I have seen a few people on here state that concatenating queries using mysql_real_escape_string
will not protect you (entirely) from SQL injection attacks.
但是,我还没有看到一个输入示例,该示例说明了mysql_real_escape_string
不能保护您免受攻击的攻击.大多数示例都忘记了mysql_query
仅限于一个查询,并且错误地使用了mysql_real_escape_string
.
However, I am yet to see an example of input that illustrates an attack that mysql_real_escape_string
would not protect you from. The majority of examples forget that mysql_query
is limited to one query and use mysql_real_escape_string
incorrectly.
我能想到的唯一示例如下:
The only example I can think of is the following:
mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input));
这不会保护您免受以下输入的干扰:
This would not protect you from the following input:
5 OR 1=1
我认为这是对mysql_real_escape_string
的错误使用,而不是一个缺点,它是为字符串而不是数字值而设计的.您应该强制转换为数字类型,或者如果要在消毒时将输入视为字符串,则应在查询中执行相同的操作,并在其两边加上引号.
I would see this as incorrect usage of mysql_real_escape_string
rather than a shortcoming, it is designed for strings not numeric values. You should either cast to a numeric type or if you are going to treat the input as a string when sanitising you should do the same in your query and wrap quotation marks around it.
谁能提供一个输入示例,它可以绕过mysql_real_escape_string
而不依赖于错误地处理数字值,或者忘记mysql_query
只能执行一个查询?
Can anyone provide an example of input that can get around mysql_real_escape_string
that does not rely on incorrect handling of numeric values or forget that mysql_query
can only execute one query?
我对mysql_real_escape_string
的局限性感兴趣,并且没有将其与替代项进行比较,我意识到对于新项目有更好的选择,并且对此没有争议.
I am interested in the limitations of mysql_real_escape_string
and not comparing it to alternatives, I realise there are better options for new projects and am not disputing that.
推荐答案
mysql_real_escape_string
或mysql_扩展名的主要缺点是,与其他更现代的API(特别是准备好的API)相比,它很难正确应用.陈述. mysql_real_escape_string
应该仅在一种情况下使用:转义用作引号之间SQL语句中的值的文本内容.例如:
The main shortcoming of mysql_real_escape_string
, or of the mysql_ extension in general, is that it is harder to apply correctly than other, more modern APIs, especially prepared statements. mysql_real_escape_string
is supposed to be used in exactly one case: escaping text content that is used as a value in an SQL statement between quotes. E.g.:
$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
^^^^^^
mysql_real_escape_string
确保上述上下文中的$value
不会弄乱SQL语法.它不起作用,您可能会在这里想到:
mysql_real_escape_string
makes sure that the $value
in the above context does not mess up the SQL syntax. It does not work as you may think here:
$sql = "... `foo` = $value ...";
或此处:
$sql = "... `$value` ...";
或此处:
$sql = mysql_real_escape_string("... `foo` = '$value' ...");
如果应用于在SQL语句中带引号的字符串以外的任何上下文中使用的值,则会被错误地使用,并且可能会或可能不会弄乱生成的语法和/或允许某些人提交可能启用SQL注入攻击的值. mysql_real_escape_string
的用例非常狭窄,但很少能正确理解.
If applied to values which are used in any context other than a quoted string in an SQL statement, it is misapplied and may or may not mess up the resulting syntax and/or allow somebody to submit values which may enable SQL injection attacks. The use case of mysql_real_escape_string
is very narrow, but is seldom correctly understood.
使用mysql_real_escape_string
使自己陷入困境的另一种方法是使用错误的方法设置数据库连接编码时.您应该这样做:
Another way to get yourself into hot water using mysql_real_escape_string
is when you set the database connection encoding using the wrong method. You should do this:
mysql_set_charset('utf8', $link);
您可以也可以这样做:
mysql_query("SET NAMES 'utf8'", $link);
问题在于后者绕过了mysql_ API,后者仍然认为您正在使用latin1
(或其他方式)与数据库进行通信.现在使用mysql_real_escape_string
时,它将假定错误的字符编码和转义字符串与数据库稍后解释它们的方式不同.通过运行SET NAMES
查询,您在mysql_客户端API如何处理字符串与数据库如何解释这些字符串之间创建了一条裂痕.可用于某些多字节字符串情况下的注入攻击.
The problem is that the latter bypasses the mysql_ API, which still thinks you're talking to the database using latin1
(or something else). When using mysql_real_escape_string
now, it will assume the wrong character encoding and escape strings differently than the database will interpret them later. By running the SET NAMES
query, you have created a rift between how the mysql_ client API is treating strings and how the database will interpret these strings. This can be used for injection attacks in certain multibyte string situations.
如果正确应用,我不知道mysql_real_escape_string
中存在基本的注入漏洞.尽管如此,主要的问题是,错误地应用它非常容易,这很容易打开.漏洞.
There are no fundamental injection vulnerabilities in mysql_real_escape_string
that I am aware of if it is applied correctly. Again though, the main problem is that it is terrifyingly easy to apply it incorrectly, which opens up vulnerabilities.
这篇关于mysql_real_escape_string的缺点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!