What's the difference between PHP's addslashes and mysql(i)_escape_string? [duplicate]

不想你离开。 提交于 2019-11-29 02:31:33
Jon

First of all: do not use mysql_escape_string, it is deprecated (for a reason)!

If you have to support a legacy application that connects to the database through the mysql extension (which has been deprecated), use mysql_real_escape_string instead. Otherwise switch immediately to mysqli, where prepared statements and bound parameters provide a more robust mechanism for escaping user input.

That said, the answer can be found by reading the description of mysql_real_escape_string and addslashes:

Difference #1

addslashes does not know anything about MySql connection encodings. If you pass it a string containing bytes representing an encoding other than the encoding used by the MySql connection, it will happily escape all bytes having the values of the characters ', ", \ and \x00. This may not be the same as all the characters ', ", \ and \x00 if you are using an encoding other than 8-bit encodings and UTF-8. The result will be that the string received by MySql will be corrupted.

To trigger this bug, try using iconv to convert your variable to UTF-16 and then escape it with addslashes. See what your database receives.

This is one reason why addslashes should not be used for escaping.

Difference #2

In contrast to addslashes, mysql_real_escape_string also escapes the characters \r, \n, and \x1a. It appears that these characters have to be escaped as well when talking to MySql, otherwise a malformed query may be the result

This is the other reason why addslashes should not be used for escaping.

Chris Shiflett demonstrates a real world case where escaping SQL using addslashes() fails, and mysql_real_escape_string() is the only way to go.

How does this help? If I want to attempt an SQL injection attack against a MySQL database, having single quotes escaped with a backslash is a bummer. If you're using addslashes(), however, I'm in luck. All I need to do is inject something like 0xbf27, and addslashes() modifies this to become 0xbf5c27, a valid multi-byte character followed by a single quote. In other words, I can successfully inject a single quote despite your escaping. That's because 0xbf5c is interpreted as a single character, not two. Oops, there goes the backslash.

....

Despite the use of addslashes(), I'm able to log in successfully without knowing a valid username or password. I can simply exploit the SQL injection vulnerability.

To avoid this type of vulnerability, use mysql_real_escape_string(), prepared statements, or any of the major database abstraction libraries.

now this is admittedly a rare edge case, but a demonstration of why people are so adamant about using the database specific escape functions. Only the database library can know for sure what kind of escaping is needed. Different wrappers, character sets and SQL flavours (like MS SQL server) need different escaping. Ignoring that fact is how vulnerabilities are born.

They are identical in that you should be using neither of them, because you should be using placeholders rather than building SQL from untrusted data.

See http://bobby-tables.com/php.html for how to do it the right way.

It's foremost a charset issue. What addslashes() does would be sufficient for escaping data intermixed with SQL commands, if the data was purely ASCII. But besides UTF-8 encoding variations, MySQL in some configuration also allows fringe charsets like UCS2 (UTF-16) or GB/Big5 chinese charsets. There it's insufficient to just escape the raw ascii code of ' into \'. And then the MySQL way of escaping strings was never very much SQL-standards-compliant to begin with. It might be deprecated in future releases of the MySQL server.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!