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 相关文章推荐
使用php4加速网络传输
Oct 09 PHP
通俗易懂的php防注入代码
Apr 07 PHP
php.ini 配置文件的深入解析
Jun 17 PHP
php生成缩略图示例代码分享(使用gd库实现)
Jan 20 PHP
php简单的留言板与回复功能具体实现
Feb 19 PHP
PHP中redis的用法深入解析
Feb 20 PHP
PHP防盗链代码实例
Aug 27 PHP
PHP获取音频文件的相关信息
Jun 22 PHP
PHP list() 将数组中的值赋给变量的简单实例
Jun 13 PHP
Laravel日志用法详解
Oct 09 PHP
Laravel5中防止XSS跨站攻击的方法
Oct 10 PHP
php实现的mysqldb读写分离操作类示例
Feb 07 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
一次编写,随处运行
2006/10/09 PHP
不支持fsockopen但支持culr环境下下ucenter与modoer通讯问题
2011/08/12 PHP
CI框架数据库查询缓存优化的方法
2016/11/21 PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
2017/10/13 PHP
PHP 枚举类型的管理与设计知识点总结
2020/02/13 PHP
jQuery使用手册之 事件处理
2007/03/24 Javascript
jQuery 位置插件
2008/12/25 Javascript
JavaScript 拾碎[三] 使用className属性
2010/10/16 Javascript
js实现网页标题栏闪烁提示效果实例分析
2014/11/20 Javascript
jQuery Tags Input Plugin(添加/删除标签插件)详解
2016/06/20 Javascript
Centos7 中安装 Node.js v4.4.4
2016/11/03 Javascript
javascript正则表达式模糊匹配IP地址功能示例
2017/01/06 Javascript
微信小程序删除处理详解
2017/08/16 Javascript
详解vue-flickity的fullScreen功能实现
2020/04/07 Javascript
原生JS实现天气预报
2020/06/16 Javascript
javascript实现简易计算器功能
2020/09/23 Javascript
python使用minimax算法实现五子棋
2019/07/29 Python
Python numpy多维数组实现原理详解
2020/03/10 Python
python中查看.db文件中表格的名字及表格中的字段操作
2020/07/07 Python
Python Matplotlib绘图基础知识代码解析
2020/08/31 Python
总结python 三种常见的内存泄漏场景
2020/11/20 Python
全球500多个机场的接送服务:Suntransfers
2019/06/03 全球购物
会计自荐书
2013/12/02 职场文书
交通安全教育制度
2014/02/02 职场文书
《赠汪伦》教学反思
2014/04/12 职场文书
三好学生演讲稿范文
2014/04/26 职场文书
民事诉讼授权委托书范文
2014/08/02 职场文书
安全责任书范文
2014/08/25 职场文书
2014年禁毒工作总结
2014/11/24 职场文书
2014年应急管理工作总结
2014/11/26 职场文书
餐厅收银员岗位职责
2015/04/07 职场文书
中国文明网2015年“向国旗敬礼”活动网上签名寄语
2015/09/24 职场文书
房产销售员2015年终工作总结
2015/10/22 职场文书
如何用RabbitMQ和Swoole实现一个异步任务系统
2021/05/29 PHP
详细聊一聊mysql的树形结构存储以及查询
2022/04/05 MySQL
nginx配置限速限流基于内置模块
2022/05/02 Servers