20

为什么我们需要一个特定于数据库的函数,比如 mysql_real_escape_string()?addlashes() 不能做什么?

暂时忽略参数化查询的优越替代方案,仅使用 addlashes() 的 web 应用程序仍然容易受到 SQL 注入的攻击,如果是,如何?

4

11 回答 11

19

它将斜杠添加到:

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

其中addslashes 只添加斜线到

' \ and NUL

Ilias 文章也非常详细地介绍了它的功能

于 2009-02-10T23:32:20.443 回答
19

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

于 2009-02-10T23:39:53.983 回答
5

gs 严厉反对的答案实际上是正确的。

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

在这种情况下,只有双倍语法才能工作,并且您使用的任何应用程序都使用了 addlashes(或其他临时转义方法)将中断。mysql_real_escape_string 将使用最适合连接的 sql_mode 的任何转义方法。

如果您仍在使用那些重复使用较低 128 个字符的讨厌的东亚编码,那么多字节编码问题也很重要,但您确实想改用 UTF-8。另一方面,\n 转义无关紧要,因为 MySQL 可以完美地处理语句中的原始换行符。

于 2009-02-11T01:31:53.730 回答
4

mysql_real_escape_string的作用远不止于此addslashes

addlashes 在纯 ascii 上运行,无需了解数据库。它逃脱:

  • '\'
  • "\"
  • \\\
  • 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 中)
  • 如果 $mysql 中链接的数据库使用宽字符集,则可以执行多字节(ascii)到宽字符的转换。

我真的不知道 PHP 如何在内部存储字符串,但关键是当您使用mysql_real_escape_string. 我想主要的区别是mysql_real_escape_string 考虑连接的字符集,哪里addslashes不能(它甚至不知道你连接到什么数据库)。

于 2013-05-08T14:50:53.233 回答
3

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

对于 MySQL,这意味着:

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

(来自手册。)

于 2009-02-10T23:30:09.730 回答
2

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

事实上,大多数时候我们没有。
一些极其罕见的编码需要此功能,并稍微美化 mysql 日志和转储。

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

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

addlashes() 不能做什么?

它可以在一些罕见的编码的情况下保护 SQL字符串文字

但是,它无法自行完成。必须mysql_set_charset()首先使用函数设置正确的编码。如果这个函数没有被使用,它mysql_real_escape_string() 的行为方式与addslashes()字符集处理完全一样——根本没有区别

于 2013-05-08T21:01:53.950 回答
1

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

于 2009-02-10T23:31:25.533 回答
1

根据PHP 手册

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

于 2009-02-10T23:35:12.323 回答
1

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

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

于 2009-02-11T03:39:16.560 回答
0

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

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

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

于 2009-02-10T23:30:08.390 回答
0

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

为什么你想先做addslashes然后你会在显示数据之前删除那个斜杠并且仍然addslashes不如mysql_real_escape_string高效,如果你使用mysql_query之类的db函数进行查询,请使用mysql_real_escape_string,或者我认为带有prepare的PDO是更好的方法,因为 mysql_real_escape_string 是特定于数据库的

于 2011-02-24T15:52:12.167 回答