为什么我们需要一个特定于数据库的函数,比如 mysql_real_escape_string()?addlashes() 不能做什么?
暂时忽略参数化查询的优越替代方案,仅使用 addlashes() 的 web 应用程序仍然容易受到 SQL 注入的攻击,如果是,如何?
为什么我们需要一个特定于数据库的函数,比如 mysql_real_escape_string()?addlashes() 不能做什么?
暂时忽略参数化查询的优越替代方案,仅使用 addlashes() 的 web 应用程序仍然容易受到 SQL 注入的攻击,如果是,如何?
它将斜杠添加到:
\x00, \n, \r, \, ', " and \x1a. characters.
其中addslashes 只添加斜线到
' \ and NUL
Ilias 文章也非常详细地介绍了它的功能
在处理多字节编码字符串时,Addslashes 通常不够好。
gs 严厉反对的答案实际上是正确的。
标准 SQL 使用加倍来转义文字撇号。MySQL 为转义使用反斜杠的非标准使用是默认设置,但它可以被禁用并且通常是禁用的,特别是在 sql_mode ANSI 中。
在这种情况下,只有双倍语法才能工作,并且您使用的任何应用程序都使用了 addlashes(或其他临时转义方法)将中断。mysql_real_escape_string 将使用最适合连接的 sql_mode 的任何转义方法。
如果您仍在使用那些重复使用较低 128 个字符的讨厌的东亚编码,那么多字节编码问题也很重要,但您确实想改用 UTF-8。另一方面,\n 转义无关紧要,因为 MySQL 可以完美地处理语句中的原始换行符。
mysql_real_escape_string的作用远不止于此addslashes
。
addlashes 在纯 ascii 上运行,无需了解数据库。它逃脱:
'
→\'
"
→\"
\
→\\
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
. 我想主要的区别是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()?
事实上,大多数时候我们没有。
一些极其罕见的编码需要此功能,并稍微美化 mysql 日志和转储。
一个只使用addslashes() 的webapp 是否仍然容易受到SQL 注入的攻击?
只要它使用任何单字节字符集或 utf8 -使用 addlashes() 就完全安全。
addlashes() 不能做什么?
它可以在一些罕见的编码的情况下保护 SQL字符串文字。
但是,它无法自行完成。必须mysql_set_charset()
首先使用函数设置正确的编码。如果这个函数没有被使用,它mysql_real_escape_string()
的行为方式与addslashes()
字符集处理完全一样——根本没有区别。
我知道的唯一真正的区别是 mysql_real_escape_string() 在转义输入字符串时会考虑数据库的字符集。这两个函数都不会转义通配符 % 和 _ ,这仍然会使脚本对某些 SQL 注入开放。
根据PHP 手册:
mysql_real_escape_string() 调用 MySQL 的库函数 mysql_real_escape_string,该函数在以下字符前添加反斜杠:\x00、\n、\r、\、'、" 和 \x1a。
PHP 的 mysql_real_escape_string 函数或多或少会询问 mysql 哪些字符需要转义,其中的 addlashses 函数只会在任何单引号 (')、双引号 (")、反斜杠 () 前面添加一个反斜杠或 NUL(NULL 字节)字符。
这两个实际效果是,addslashes 往往不适用于多字节字符,更重要的是,通过询问 mysql 需要转义哪些字符,可以避免未来可能的兼容性。使用 assslashes 有点像将几个特定字符硬编码到转义序列中。
它应该以其他引用工具没有的方式为 MySQL 转义字符串。
然而,更可取的是使用 mysqli 接口,并使用参数化的准备查询,而不是尝试确保所有字符串都正确转义。使用参数化查询消除了对这种凌乱的字符串工作的需要,并大大降低了 SQL 注入的风险。
编辑:我将澄清一下为什么我考虑引用一个坏主意:很容易忘记何时何地需要引用 - 你的变量是字符串还是数字,是否已经被引用等等。参数化查询没有这些问题,并且完全不需要引用。
根据我的理解 mysql_real_escape_string() 更精确地完成工作,因为它与 db 通信首先检查需要编码的内容,然后进行相应的编码,不是吗?因此,它可以更有效地工作
为什么你想先做addslashes然后你会在显示数据之前删除那个斜杠并且仍然addslashes不如mysql_real_escape_string高效,如果你使用mysql_query之类的db函数进行查询,请使用mysql_real_escape_string,或者我认为带有prepare的PDO是更好的方法,因为 mysql_real_escape_string 是特定于数据库的