mysql_real_escape_string()做了什么,addslashes()没有?

时间:2009-02-10 23:23:30

标签: php security sql-injection

为什么我们需要特定于数据库的函数,如mysql_real_escape_string()?它能做什么,addslashes()不是吗?

暂时忽略参数化查询的优秀替代方案,是一个使用addslashes()的webapp,它仍然容易受到SQL注入攻击,如果是,那么如何?

11 个答案:

答案 0 :(得分:19)

它添加了斜杠:

\x00, \n, \r, \, ', " and \x1a. characters.

其中addslashes只添加斜杠

' \ and NUL

Ilias article在功能上也非常详细

答案 1 :(得分:19)

在处理多字节编码字符串时,Addslashes通常不够好。

答案 2 :(得分:5)

gs严厉贬低的答案实际上是对的。

标准SQL使用加倍来转义文字撇号。 MySQL的非标准反斜杠用于转义是默认设置,但它可以被禁用,特别是在sql_mode ANSI中。

在这种情况下,只有doubled语法才有效,并且使用addslashes(或其他ad-hoc转义方法)的任何应用程序都会中断。 mysql_real_escape_string将使用最适合连接的sql_mode的转义方法。

如果您仍在使用那些重复使用较低128个字符的令人讨厌的东亚编码,那么多字节编码问题也很重要,但实际上您真的希望使用UTF-8。另一方面,无需担心,因为MySQL可以非常乐意在声明中处理原始换行。

答案 3 :(得分:4)

mysql_real_escape_stringaddslashes

addslashes在纯ascii上运行,不知道有关数据库的任何信息。它逃脱了:

  • '\'
  • "\"
  • \\\
  • ASCII 0\0

mysql_real_escape_string的目的是“创建一个可以在SQL语句中使用的合法SQL字符串。” mysql_real_escape_string考虑连接的当前字符集(这就是为什么你必须总是传递一个有效的$ mysql对象)。

它执行以下操作(取自MySQL C API文档):

  • 编码:\'",ASCII 0\n\rControl+Z不会导致问题的方式
  • 确保0字节终止字符串(在C api中)
  • 如果链接到$ mysql的数据库使用宽字符集,则
  • 可以执行多字节(ascii)到宽字符转换。

我真的不知道PHP如何在内部存储字符串,但重点是当你使用mysql_real_escape_string时PHP可以使用它。我想主要的不同点是mysql_real_escape_string 会考虑连接的字符集addslashes不能(它甚至不知道你连接的是什么数据库)。

答案 4 :(得分:3)

somedb_real_escape_string()是特定于数据库的,addslashes()不是。

对于MySQL,这意味着:

  

mysql_real_escape_string()调用   MySQL的库函数   mysql_real_escape_string,其中   在下面添加反斜杠   字符:\ x00,\ n,\ r,\,',“和   \ X1A。

(来自手册。)

答案 5 :(得分:2)

  

为什么我们需要特定于数据库的函数,如mysql_real_escape_string()?

实际上,大部分时间我们都不这样做 一些非常罕见的编码需要此函数,并且可以对mysql日志和转储进行美化。

  

是一个使用addslashes()的webapp,它仍然容易受到SQL注入的攻击吗?

只要它使用任何单字节字符集或utf8 - ,使用addslashes()就可以完全安全。

  

addslashes()不能做什么?

如果有一些罕见的编码,它可以保护SQL 字符串文字

但是,它无法自行完成。必须首先使用mysql_set_charset()函数设置正确的编码。如果未使用此功能,mysql_real_escape_string() 在字符集处理方面的行为与addslashes()完全相同 - 根本没有区别

答案 6 :(得分:1)

我所知道的唯一真正的区别是mysql_real_escape_string()在转义输入字符串时会考虑数据库的字符集。这两个函数都不会转义通配符字符%和_,这仍然会使脚本打开一些SQL注入。

答案 7 :(得分:1)

根据PHP manual

  

mysql_real_escape_string()调用MySQL的库函数mysql_real_escape_string,该函数将反斜杠添加到以下字符:\ x00,\ n,\ r,\,',“和\ x1a。

答案 8 :(得分:1)

PHP的mysql_real_escape_string函数或多或少会询问mysql需要转义哪些字符,其中addslashses函数只会在前面添加一个反斜杠和任何单引号(') ,双引号(“),反斜杠()或NUL(NULL字节)字符。

两个实际效果是,addslashes往往不能很好地处理多字节字符,更重要的是,通过询问mysql需要转义哪些字符,可以避免将来可能的兼容性。使用assslashes有点像将几个特定字符硬编码到转义序列中。

答案 9 :(得分:0)

它应该以其他引用设施没有的方式转义MySQL的字符串。

然而,更为可取的是使用mysqli接口,并使用参数化准备的查询,而不是尝试确保所有字符串都被正确转义。使用参数化查询消除了对这种混乱的字符串工作的需要,并大大降低了SQL注入的风险。

编辑:我会澄清一下为什么我会考虑引用一个坏主意:很容易忘记你需要引用的时间和地点 - 无论你的变量是字符串还是数字,是否已被引用,参数化查询没有这些问题,并且引用的需要完全被删除。

答案 10 :(得分:0)

根据我的理解,mysql_real_escape_string()更精确地完成工作,因为它与db通信,首先检查需要编码的内容然后进行相应的编码,不是吗?所以它的工作效率更高

为什么你想首先做addslashes然后你会在显示数据之前删除斜线,而且仍然不会像mysql_real_escape_string一样有效,如果你使用mysql_query像db函数进行查询,请使用mysql_real_escape_string,或者我认为PDO准备好了是更好的方法,因为mysql_real_escape_string是db特定的