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 Session变量不能传送到下一页的解决方法
Nov 27 PHP
PHP中用接口、抽象类、普通基类实现“面向接口编程”与“耦合方法”简述
Mar 23 PHP
php生成静态文件的多种方法分享
Jul 17 PHP
Erlang的运算符(比较运算符,数值运算符,移位运算符,逻辑运算符)
Jul 23 PHP
php 根据url自动生成缩略图并处理高并发问题
Jan 23 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
May 12 PHP
[原创]php获取数组中键值最大数组项的索引值
Mar 17 PHP
php如何连接sql server
Oct 16 PHP
PHP从数组中删除元素的四种方法实例
May 12 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
Django中通过定时任务触发页面静态化的处理方式
Aug 29 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 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 用数组降低程序的时间复杂度
2009/12/04 PHP
PHP获取文件夹大小函数用法实例
2015/07/01 PHP
PHP中Http协议post请求参数
2015/11/02 PHP
PHP中Session ID的实现原理实例分析
2019/08/17 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
网页里控制图片大小的相关代码
2006/06/13 Javascript
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
node.js中的path.join方法使用说明
2014/12/08 Javascript
JavaScript数据结构与算法之链表
2016/01/29 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
简单谈谈JS数组中的indexOf方法
2016/10/13 Javascript
AngularJS自定义指令之复制指令实现方法
2017/05/18 Javascript
详解如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
2017/06/01 jQuery
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
vue-cli的eslint相关用法
2017/09/29 Javascript
angularJs中$http获取后台数据的实例讲解
2018/08/08 Javascript
Angular服务Request异步请求的实例讲解
2018/08/13 Javascript
JS实现数组的增删改查操作示例
2018/08/29 Javascript
使用Vue实现移动端左滑删除效果附源码
2019/05/16 Javascript
vue element-ui读取pdf文件的方法
2019/11/26 Javascript
[54:02]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 IG vs VGJ.T
2018/04/03 DOTA
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
跟老齐学Python之不要红头文件(1)
2014/09/28 Python
视觉直观感受若干常用排序算法
2017/04/13 Python
python去除扩展名的实例讲解
2018/04/23 Python
Python图像处理之颜色的定义与使用分析
2019/01/03 Python
使用python3构建文件传输的方法
2019/02/13 Python
用Python实现校园通知更新提醒功能
2019/11/23 Python
pycharm激活码2020最新分享适用pycharm2020最新版亲测可用
2020/11/22 Python
HTML5中drawImage用法分析
2014/12/01 HTML / CSS
提供世界各地便宜的机票:Sky-tours
2016/07/21 全球购物
线程同步的方法
2016/11/23 面试题
传播学毕业生求职信
2013/10/11 职场文书
大学毕业感言50字
2014/02/07 职场文书
婚内房产协议书范本
2014/10/02 职场文书
世界遗产的导游词
2015/02/13 职场文书