为什么我们需要特定于数据库的函数,如mysql_real_escape_string()?它能做什么,addslashes()不是吗?
暂时忽略参数化查询的优秀替代方案,是一个使用addslashes()的webapp,它仍然容易受到SQL注入攻击,如果是,那么如何?
答案 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_string比addslashes
'
→\'
"
→\"
\
→\\
0
→\0
。mysql_real_escape_string的目的是“创建一个可以在SQL语句中使用的合法SQL字符串。” mysql_real_escape_string考虑连接的当前字符集(这就是为什么你必须总是传递一个有效的$ mysql对象)。
它执行以下操作(取自MySQL C API文档):
\
,'
,"
,ASCII 0
,\n
,\r
和Control+Z
不会导致问题的方式0
字节终止字符串(在C api中)我真的不知道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特定的