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,尤其是准备好的语句.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屋!