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 相关文章推荐
用PHP生成html分页列表的代码
Mar 18 PHP
PHP常用技巧总结(附函数代码)
Feb 04 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
Jun 05 PHP
php定界符
Jun 19 PHP
smarty模板引擎之配置文件数据和保留数据
Mar 30 PHP
php 魔术常量详解及实例代码
Dec 04 PHP
php文件上传及下载附带显示文件及目录功能
Apr 27 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
May 09 PHP
PHP生成各种随机验证码的方法总结【附demo源码】
Jun 05 PHP
php基于协程实现异步的方法分析
Jul 17 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
Apr 23 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
Sep 17 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
2019年中国咖啡业现状与发展趋势
2021/03/04 咖啡文化
提示Trying to clone an uncloneable object of class Imagic的解决
2011/10/27 PHP
ThinkPHP模板中判断volist循环的最后一条记录的验证方法
2014/07/01 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
JavaScript中为元素加上name属性的方法
2011/05/09 Javascript
js实现运动logo图片效果及运动元素对象sportBox使用方法
2012/12/25 Javascript
jQuery实现跨域iframe接口方法调用
2015/03/14 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
2015/08/31 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
教你如何在Node.js中使用jQuery
2016/08/28 Javascript
javascript判断firebug是否开启的方法
2016/11/23 Javascript
Bootstrap Table使用整理(五)之分页组合查询
2017/06/09 Javascript
jQuery实现frame之间互通的方法
2017/06/26 jQuery
微信小程序 共用变量值的实现
2017/07/12 Javascript
关于Ajax的原理以及代码封装详解
2017/09/08 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
javascript json字符串到json对象转义问题
2019/01/22 Javascript
express + jwt + postMan验证实现持久化登录
2019/06/05 Javascript
Python中decorator使用实例
2015/04/14 Python
Django中的Signal代码详解
2018/02/05 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
Python学习笔记之列表推导式实例分析
2019/08/13 Python
解决pytorch DataLoader num_workers出现的问题
2020/01/14 Python
python实现从ftp服务器下载文件
2020/03/03 Python
Python环境管理virtualenv&amp;virtualenvwrapper的配置详解
2020/07/01 Python
英国知名小木屋定制网站:Tiger Sheds
2020/03/06 全球购物
市场营销专业推荐信
2013/11/03 职场文书
建议书标准格式
2014/03/12 职场文书
班组建设经验交流材料
2014/05/12 职场文书
医院营销工作计划
2015/01/16 职场文书
爱晚亭导游词
2015/02/09 职场文书
三八妇女节慰问信
2015/02/14 职场文书
生产车间主任岗位职责
2015/04/08 职场文书
放牛班的春天观后感
2015/06/01 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
MySQL优化之如何写出高质量sql语句
2021/05/17 MySQL