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 相关文章推荐
模仿OSO的论坛(三)
Oct 09 PHP
PHP 中的面向对象编程:通向大型 PHP 工程的办法
Dec 03 PHP
php中支持多种编码的中文字符串截取函数!
Mar 20 PHP
php session处理的定制
Mar 16 PHP
php class中self,parent,this的区别以及实例介绍
Apr 24 PHP
PHP中判断变量为空的几种方法小结
Nov 12 PHP
PHP借助phpmailer发送邮件
May 11 PHP
PHP获取当前相对于域名目录的方法
Jun 26 PHP
PHP 错误处理机制
Jul 06 PHP
基于PHP后台的Android新闻浏览客户端
May 23 PHP
数组任意位置插入元素,删除特定元素的实例
Mar 02 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
Jul 19 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
Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)
2011/04/18 PHP
php删除txt文件指定行及按行读取txt文档数据的方法
2017/01/30 PHP
PHP大文件切割上传并带进度条功能示例
2019/07/01 PHP
JS下拉缓冲菜单示例代码
2013/08/30 Javascript
JQuery自动触发事件的方法
2015/06/13 Javascript
jquery表单验证需要做些什么
2015/11/17 Javascript
IE和Firefox之间在JavaScript语法上的差异
2016/04/22 Javascript
Angular 2应用的8个主要构造块有哪些
2016/10/17 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
webpack 打包压缩js和css的方法示例
2018/03/20 Javascript
Vue组件通信的几种实现方法
2019/04/25 Javascript
深入理解令牌认证机制(token)
2019/08/22 Javascript
Layui实现数据表格中鼠标悬浮图片放大效果,离开时恢复原图的方法
2019/09/11 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
vue中封装axios并实现api接口的统一管理
2020/12/25 Vue.js
[47:52]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第二场 11.26
2020/11/30 DOTA
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
Python定时执行之Timer用法示例
2015/05/27 Python
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
深入分析python数据挖掘 Json结构分析
2018/04/21 Python
基于Python+Appium实现京东双十一自动领金币功能
2019/10/31 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
html5如何及时更新缓存文件(js、css或图片)
2013/06/24 HTML / CSS
浅析HTML5中header标签的用法
2016/06/24 HTML / CSS
加拿大女包品牌:Matt & Nat
2017/05/12 全球购物
乌克兰数字设备、配件和智能技术的连锁商店:KTC
2020/08/18 全球购物
PHP如何设置和取得Cookie值
2015/06/30 面试题
财务会计人员岗位职责
2013/11/30 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
家长对孩子评语
2014/01/30 职场文书
电气工程及其自动化专业毕业生自荐信
2014/06/21 职场文书
治庸问责心得体会
2014/09/12 职场文书
捐助倡议书
2015/01/19 职场文书
委托书英文
2015/01/28 职场文书