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+MySQL5.0中文乱码解决方法
Nov 20 PHP
PHP中查询SQL Server或Sybase时TEXT字段被截断的解决方法
Mar 10 PHP
php iconv() : Detected an illegal character in input string
Dec 05 PHP
在WINDOWS中设置计划任务执行PHP文件的方法
Dec 19 PHP
smarty获得当前url的方法分享
Feb 14 PHP
PHP实现显示照片exif信息的方法
Jul 11 PHP
PHP实现事件机制的方法
Jul 10 PHP
将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
Mar 03 PHP
php 静态属性和静态方法区别详解
Apr 09 PHP
thinkPHP3.2.3实现阿里大于短信验证的方法
Jun 06 PHP
PHP count_chars()函数讲解
Feb 14 PHP
PHP中命名空间的使用例子
Mar 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
四月新番又没了,《Re:从零开始的异世界生活》第二季延期至7月播出
2020/05/06 日漫
教你如何把一篇文章按要求分段
2006/10/09 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
[原创]PHP实现SQL语句格式化功能的方法
2017/07/28 PHP
js之WEB开发调试利器:Firebug 下载
2007/01/13 Javascript
jquery tools之tooltip
2009/07/25 Javascript
多浏览器兼容的获取元素和鼠标的位置的js代码
2009/12/15 Javascript
javascript客户端解决方案 缓存提供程序
2010/07/14 Javascript
jQuery EasyUI API 中文文档 - Tabs标签页/选项卡
2011/10/01 Javascript
用js实现小球的自由移动代码
2013/04/22 Javascript
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
jquery toolbar与网页浮动工具条具体实现代码
2014/01/12 Javascript
JavaScript支持的最大递归调用次数分析
2014/06/24 Javascript
基于javascript实现图片左右切换效果
2016/01/25 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
浅谈js的异步执行
2016/10/18 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
解决vue.js this.$router.push无效的问题
2018/09/03 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
2018/10/20 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
微信小程序以7天为周期连续签到7天功能效果的示例代码
2020/08/20 Javascript
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
Django分页查询并返回jsons数据(中文乱码解决方法)
2018/08/02 Python
详解Django-restframework 之频率源码分析
2019/02/27 Python
pycharm运行程序时看不到任何结果显示的解决
2020/02/21 Python
Python使用monkey.patch_all()解决协程阻塞问题
2020/04/15 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
为娇小女性量身打造:Petite Studio
2018/11/01 全球购物
C面试题
2015/10/08 面试题
优秀老员工获奖感言
2014/02/15 职场文书
企业安全生产目标责任书
2014/07/23 职场文书
群众路线个人自我剖析材料
2014/10/07 职场文书
公民授权委托书
2014/10/15 职场文书
幼儿园小班开学寄语
2015/05/27 职场文书