PHP函数addslashes和mysql_real_escape_string的区别


Posted in PHP onApril 22, 2014

首先:不要使用mysql_escape_string,它已被弃用,请使用mysql_real_escape_string代替它。

mysql_real_escape_string和addslashes的区别在于:

区别一:

addslashes不知道任何有关MySQL连接的字符集。如果你给所使用的MySQL连接传递一个包含字节编码之外的其他编码的字符串,它会很愉快地把所有值为字符‘、“、\和\x00的字节进行转义。如果你正在使用不同于8位和UTF-8的其它字符,这些字节的值不一定全部都是表示字符‘、“、\和\x00。可能造成的结果是,MySQL接收这些字符后出现错误。

如果要修正这个bug,可尝试使用iconv函数,将变量转为UTF-16,然后再使用addslashes进行转义。

这是不使用addslashes进行转义的原因之一。

区别二:

与addslashes对比,mysql_real_escape_string同时还对\r、\n和\x1a进行转义。看来,这些字符必须正确地告诉MySQL,否则会得到错误的查询结果。

这是不使用addslashes进行转义的另一个原因。

addslashes V.S. mysql_real_escape_string

在GBK里,0xbf27不是一个合法的多字符字符,但0xbf5c却是。在单字节环境里,0xbf27被视为0xbf后面跟着0×27(‘),同时0xbf5c被视为0xbf后面跟着0x5c(\)。

一个用反斜杠转义的单引号,是无法有效阻止针对MySQL的SQL注入攻击的。如果你使用addslashes,那么,我(攻击者,下同)是很幸运的。我只要注入一些类似0xbf27,然后addslashes将它修改为0xbf5c27,一个合法的多字节字符后面接着一个单引号。换句话说,我可以无视你的转义,成功地注入一个单引号。这是因为0xbf5c被当作单字节字符,而非双字节。

在这个演示中,我将使用MySQL 5.0和PHP的mysqli扩展。如果你想尝试,请确保你使用GBK。

创建一个名为users的表:

CREATE TABLE users(
 username VARCHAR(32) CHARACTER SET GBK,
 password VARCHAR(32) CHARACTER SET GBK,
 PRIMARY KEY(username)
);

下面的代码模拟只使用addslashes(或magic_quotes_gpc)对查询数据进行转义时的情况:
<?php
$mysql = array();
$db = mysqli_init();
$db->real_connect('localhost', 'lorui', 'lorui.com', 'lorui_db');
/* SQL注入示例 */
$_POST['username'] = chr(0xbf) . chr(0×27) . ‘ OR username = username /*'; $_POST['password'] = ‘guess'; $mysql['username'] = addslashes($_POST['username']); $mysql['password'] = addslashes($_POST['password']); $sql = “SELECT * FROM users WHERE username = ‘{$mysql['username']}' AND password = ‘{$mysql['password']}'”; $result = $db->query($sql); if ($result->num_rows) { /* 成功 */ } else { /* 失败 */ }

尽管使用了addslashes,我还是可以在不知道用户名和密码的情况下成功登录。我可以轻松的利用这个漏洞进行SQL注入。

要以免这种漏洞,使用mysql_real_escape_string、准备语句(Prepared Statements,即“参数化查询”)或者任意一款主流的数据库抽象类库。

PHP 相关文章推荐
将数字格式的计算结果转为汉字格式
Oct 09 PHP
真正的ZIP文件操作类(php)
Jul 21 PHP
wordpress之wp-settings.php
Aug 17 PHP
php 各种应用乱码问题的解决方法
May 09 PHP
PHP执行zip与rar解压缩方法实现代码
Dec 05 PHP
PHP提取字符串中的图片地址[正则表达式]
Nov 12 PHP
php网站地图生成类示例
Jan 13 PHP
php验证邮箱和ip地址最简单方法汇总
Oct 30 PHP
thinkphp多层MVC用法分析
Dec 30 PHP
PHPStrom 新建FTP项目以及在线操作教程
Oct 16 PHP
php JWT在web端中的使用方法教程
Sep 06 PHP
PHP架构及原理知识点详解
Dec 22 PHP
自己写了一个php检测文件编码的函数
Apr 21 #PHP
CodeIgniter框架提示Disallowed Key Characters的解决办法
Apr 21 #PHP
PHP5中实现多态的两种方法实例分享
Apr 21 #PHP
PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等)
Apr 21 #PHP
PHP正则提取不包含指定网址的图片地址的例子
Apr 21 #PHP
phpmyadmin打开很慢的解决方法
Apr 21 #PHP
PHP递归删除目录几个代码实例
Apr 21 #PHP
You might like
PHP中的正规表达式(二)
2006/10/09 PHP
php批量缩放图片的代码[ini参数控制]
2011/02/11 PHP
PHP 输出URL的快捷方式示例代码
2013/09/22 PHP
PHP 正则表达式小结
2015/02/12 PHP
简单谈谈PHP中strlen 函数
2016/02/27 PHP
PHP实现统计在线人数功能示例
2016/10/15 PHP
Prototype Selector对象学习
2009/07/23 Javascript
javascript 数组学习资料收集
2010/04/11 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
jQuery随机密码生成的方法
2015/03/09 Javascript
JavaScript动态生成二维码图片
2016/04/20 Javascript
JavaScript探测CSS动画是否已经完成的方法
2016/08/30 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
整理关于Bootstrap模态弹出框的慕课笔记
2017/03/29 Javascript
用vue封装插件并发布到npm的方法步骤
2017/10/18 Javascript
JS中数据结构之栈
2019/01/01 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
深入理解es6块级作用域的使用
2019/03/28 Javascript
详解nodejs http请求相关总结
2019/03/31 NodeJs
Nest.js环境变量配置与序列化详解
2021/02/21 Javascript
[02:20]DOTA2亚洲邀请赛 EHOME战队出场宣传片
2015/02/07 DOTA
[01:03:31]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第二局
2016/02/26 DOTA
python使用rabbitmq实现网络爬虫示例
2014/02/20 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
pytorch nn.Conv2d()中的padding以及输出大小方式
2020/01/10 Python
Python 生成VOC格式的标签实例
2020/03/10 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
ASOS比利时:英国线上零售商及自有品牌
2018/07/29 全球购物
应用电子专业学生的自我评价
2013/10/16 职场文书
学习雷锋标语
2014/06/25 职场文书
董事长助理工作职责范本
2014/07/01 职场文书
个人授权委托书范本格式
2014/10/12 职场文书
2016继续教育培训学习心得体会
2016/01/19 职场文书
详解Node.js如何处理ES6模块
2021/05/15 Javascript
开机音效回归! Windows 11重新引入开机铃声
2021/11/21 数码科技