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支持页面回退的两种方法
Jan 10 PHP
如何在PHP程序中防止盗链
Apr 09 PHP
php 各种应用乱码问题的解决方法
May 09 PHP
ubuntu 编译安装php 5.3.3+memcache的方法
Aug 05 PHP
php设置允许大文件上传示例代码
Mar 10 PHP
php中session过期时间设置及session回收机制介绍
May 05 PHP
PHP源码分析之变量的存储过程分解
Jul 03 PHP
smarty缓存用法分析
Dec 16 PHP
Laravel SQL语句记录方式(推荐)
May 26 PHP
PHP读取文本文件并逐行输出该行使用最多的字符与对应次数的方法
Nov 25 PHP
Zend Framework入门教程之Zend_Config组件用法详解
Dec 09 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
Dec 29 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
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
Zend Framework教程之Zend_Registry对象用法分析
2016/03/22 PHP
JQuery为textarea添加maxlength属性的代码
2010/04/07 Javascript
Jquery实现带动画效果的经典二级导航菜单
2013/03/22 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
React-Native 组件之 Modal的使用详解
2017/08/08 Javascript
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
node.js中使用Export和Import的方法
2017/09/18 Javascript
vue采用EventBus实现跨组件通信及注意事项小结
2018/06/14 Javascript
JavaScript设计模式之工厂模式简单实例教程
2018/07/03 Javascript
打通前后端构建一个Vue+Express的开发环境
2018/07/17 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
2018/10/19 Javascript
laydate如何根据开始时间或者结束时间限制范围
2018/11/15 Javascript
vue实现路由切换改变title功能
2019/05/28 Javascript
vue 组件销毁并重置的实现
2020/01/13 Javascript
js实现简单的无缝轮播效果
2020/09/05 Javascript
python用10行代码实现对黄色图片的检测功能
2015/08/10 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
Python利用sqlacodegen自动生成ORM实体类示例
2019/06/04 Python
用Python+OpenCV对比图像质量的几种方法
2019/07/15 Python
Python qrcode 生成一个二维码的实例详解
2020/02/12 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
Spring http服务远程调用实现过程解析
2020/06/11 Python
Django模型验证器介绍与源码分析
2020/09/08 Python
台湾最大网路书店:博客来
2018/03/18 全球购物
美国在线医疗分销商:MedEx Supply
2020/02/04 全球购物
.NET初级开发工程师面试题(包括Javascript)
2012/08/22 面试题
工程专业求职自荐书范文
2014/02/18 职场文书
节能环保口号
2014/06/12 职场文书
交通事故协议书范文
2014/10/23 职场文书
2014年业务员工作总结范文
2014/11/17 职场文书
毕业赠语大全
2015/06/23 职场文书
公务员廉洁从政心得体会
2016/01/19 职场文书
SONY AN-LP1 短波有源天线放大器
2021/04/22 无线电
用几道面试题来看JavaScript执行机制
2021/04/30 Javascript
Pytorch中的数据集划分&正则化方法
2021/05/27 Python