2010-08-13 78 views
33

有人可以提供一些线索上这两个函数之间的差异,从PHP手册mysql_real_escape_string VS和addslashes

和addslashes: 返回与反斜线的字符串需要在数据库查询等,这些字符将被引用的字符之前单引号('),双引号(“),反斜线()和NUL(空字节)

mysql_real_escape_string: mysql_real_escape_string()调用MySQL的库函数mysql_real_escape_string,其中前添加反斜杠以下字符:\ X00, \ n,\ r,\,',“和\ x1a。

从我收集的主要区别是\ x00,\ n \ r \ x1a哪些addslashes不逃脱,你能告诉我什么意思是?

感谢

回答

42

你们报了可能是从文档,但据我知道这未必是真实的。

addslashes为通常令人不安的字符添加斜杠。 mysql_real_escape_string转义任何MySQL需要逃脱。这可能比addslashes需要处理的更多或更少的字符。

此外,mysql_real_escape_string不一定会增加斜线以逃避。虽然我认为它可以工作,但如果你这样做的话,最近的MySQL版本通过把它们中的两个放在一起而不是通过在它之前放置斜线来避免引号。

我相信你应该总是使用你的数据提供者的转义函数而不是addslashes,因为addslashes可能会做太多或没有足够的工作来达到你使用它的目的。另一方面,mysql_real_escape_string知道如何准备将字符串嵌入到查询中。即使规格改变了如何逃避东西,突然它不是反斜杠,你应该使用了,你的代码仍然可以工作,因为mysql_real_escape_string将意识到它。

+3

ANSI SQL指定单引号可以用一行中的两个单引号表示,但mysql_real_escape_string()不会这样做 - 就我所见,它总是使用反斜线转义。如果你有一个通过加倍引号字符来逃脱MySQL版本的例子,我会对看到这个例子感兴趣。 – 2014-01-15 20:04:26

+1

@BillKarwin,PHP的'mysql_real_escape_string'调用MySQL的['mysql_real_escape_string'](http://dev.mysql.com/doc/refman/4.1/en/mysql-real-escape-string.html),它可以做任何事情逃避弦乐。 PHP文档现在说它使用黑色斜线,但MySQL文档没有提到这一点。我记得在某些时候它会用''''而不是'\''来转义,也许情况不再是这样,或者它可能需要特定的连接设置('mysql_real_escape_string'需要一个连接参数,以便它可以在检查之后检查它们所有)。 – zneak 2014-01-15 20:18:51

+1

啊哈,我测试并发现,如果你设置了'SQL_MODE = NO_BACKSLASH_ESCAPES',它的行为就像你描述的那样。我的困惑是因为'mysqldump'仍然不会做双引号字符,即使你有这个sql模式集。这意味着您可以创建一个无法在生成它的服务器上重新导入的转储文件! – 2014-01-15 20:27:54

0

忽略这两者并仅使用参数化查询。当然,除非你喜欢注射攻击。

+0

为了完整起见,您可以引用要切换到的函数/类吗?我来自Postgres的背景,所以我知道使用ps_函数或PDO,但我不知道什么支持MySQL用户的参数化查询。 – Tom 2010-08-13 00:50:13

+6

“mysql_real_escape_string”的一致使用将防止注入攻击。 – 2010-08-13 00:50:48

+2

模糊概括不是很有帮助。 – cbednarski 2010-08-13 00:53:17

13

mysql_real_escape_string()还考虑到当前连接到数据库使用的字符集。

PHP函数mysql_real_escape_string()使用相同的名称的MySQL的C API函数:http://dev.mysql.com/doc/refman/5.1/en/mysql-real-escape-string.html

由著名的PHP安全专家克里斯·夏夫利特又看了addslashes() Versus mysql_real_escape_string(),为示范,你可以得到SQL注入的攻击,即使你使用addslashes()。


其他人推荐使用查询参数,然后你不必做任何转义的动态值。我也推荐这样做,但在PHP中,您必须切换到PDO或ext/mysqli,因为纯粹的ext/mysql API不支持查询参数。

此外,可能会出现一些不能使用动态字符串值的查询参数的情况,例如全文搜索中的搜索模式。

+1

+1阅读材料。了解这些主题是很好的。 – cbednarski 2010-08-13 00:45:33

+0

“必须打开PDO”听起来对我有益! – Tom 2010-08-13 00:48:26

+0

@汤姆:是的,我更喜欢PDO,我推荐它。但是如果一个项目已经有很多使用ext/mysql的代码,那么很难说明重写所有的时间。 – 2010-08-13 01:06:12

1

有一堆历史记录mysql_escape_stringmysql_real_escape_string。他们都试图提供一个“通用”转义机制,以尽量减少sql注入攻击的可能性。

mysql_real_escape_stringaddslashes没问题,如果他们是你真正需要的 - 但他们可能不是。

由于@afrazier说,你应该 “使用PDO,而你的应用程序使用的MySQLi您可以使用此IES(当心! ”用prepared statements

1

而不是准备QUER我“ MySQL的和”)

$nick = $connect->real_escape_string($nick); 
$nick= addcslashes($nick, '%_'); 

$pass = $connect->real_escape_string($pass); 
$pass = addcslashes($pass, '%_');