mysql_real_escape_string()做了什么,addslashes()不?

为什么我们需要像mysql_real_escape_string()这样的数据库特定的函数? 它能做些什么,addslashes()不?

忽略参数化查询的优越select,是一个使用addslashes()的webapp,它仍然很容易受到SQL注入的攻击,如果是的话,怎么样?

处理多字节编码的string时,加速器通常不够好。

它增加了斜杠:

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

在addslashes只增加斜杠

 ' \ and NUL 

伊利亚斯的文章也相当详细的function

gs的严厉低调的答案其实是挺对的。

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

在这种情况下,只有加倍的语法将会起作用,并且任何您使用addslashes(或其他临时转义方法)的应用程序都将中断。 mysql_real_escape_string将使用哪个转义方法最适合连接的sql_mode。

如果您仍然在使用重复使用较低128个字符的恶意东亚编码,那么多字节编码问题也很重要,但是您真的想要使用UTF-8。 另一方面,n转义是无关紧要的,因为MySQL可以在一个声明中完美地处理原始的换行符。

mysql_real_escape_string比addslashes做的多得多。

addslashes操作纯粹的ASCII,不知道任何关于数据库。 它逃脱了:

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

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

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

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

我真的不知道PHP如何在内部存储string,但是当使用mysql_real_escape_string时,所有这一切都可用于PHP。 我猜想不同点是mysql_real_escape_string 认为连接的字符集 ,在addslashes不能(它甚至不知道你连接到哪个数据库)。

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

在MySQL的情况下,这意味着:

mysql_real_escape_string()调用MySQL的库函数mysql_real_escape_string,它将反斜杠预置为以下字符:\ x00,\ n,\ r,\,',“和\ x1a。

(从手册中)

为什么我们需要像mysql_real_escape_string()这样的数据库特定的函数?

其实大部分时间我们都没有。
这个函数对于一些非常less见的编码是必需的,并且需要对mysql日志进行优化并转储一下。

是一个使用addslashes()专门仍然容易受到SQL注入的Web应用程序?

只要它使用任何单字节字符集或utf8 – 用addslashes()完全安全。

它能做些什么,addslashes()不?

它可以保护SQL string文字的情况下,一些罕见的编码。

但是,它本身无法做到。 首先使用mysql_set_charset()函数设置正确的编码。 如果这个函数没有被使用, mysql_real_escape_string() 在字符集处理方面的行为与addslashes()行为完全一样 – 完全没有区别

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

根据PHP手册 :

mysql_real_escape_string()调用MySQL的库函数mysql_real_escape_string,它将反斜杠预置为以下字符:\ x00,\ n,\ r,\,',“和\ x1a。

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

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

它应该逃避MySQL的string,而其他引用工具则不会。

然而,最好的办法是使用mysqli接口 ,并使用参数化准备好的查询,而不是试图确保所有的string都正确地转义。 使用参数化查询可避免使用这种繁琐的string工作,并大大降低了SQL注入的风险。

编辑:我会澄清一点,为什么我认为引用一个坏主意:很容易忘记何时何地需要引用 – 是否variables是一个string或数字,是否已被引用等。参数化查询没有这些问题 ,并且引用的需要被完全消除。

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

为什么你想先做addslashes,然后你会在显示数据之前删除那些斜线,然后addslashes不如mysql_real_escape_string高效,如果你正在使用mysql_query如db函数进行查询,那么使用mysql_real_escape_string,或者我认为PDO与prepare是更好的方法,因为mysql_real_escape_string是数据库特定的