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数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
PHP HTML代码串 截取实现代码
Jun 29 PHP
PHP内核介绍及扩展开发指南―基础知识
Sep 11 PHP
PHP 将逗号、空格、回车分隔的字符串转换为数组的函数
Jun 07 PHP
测试PHP连接MYSQL成功与否的代码
Aug 16 PHP
php分页示例分享
Apr 30 PHP
php数组中删除元素之重新索引的方法
Sep 16 PHP
PHP中使用curl入门教程
Jul 02 PHP
超详细的php用户注册页面填写信息完整实例(附源码)
Nov 17 PHP
详细解读php的命名空间(一)
Feb 21 PHP
浅谈laravel框架sql中groupBy之后排序的问题
Oct 17 PHP
PHP使用Http Post请求发送Json对象数据代码解析
Jul 16 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下保存远程图片到本地的办法
2010/08/08 PHP
PHP学习笔记之数组篇
2011/06/28 PHP
php下载excel无法打开的解决方法
2013/12/24 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
PHP DB 数据库连接类定义与用法示例
2019/03/11 PHP
PHP数组与字符串互相转换实例
2020/05/05 PHP
如何用js控制css中的float的代码
2007/08/16 Javascript
jquery ajax执行后台方法
2010/03/18 Javascript
jquery 简短几句代码实现给元素动态添加及获取提示信息
2011/09/01 Javascript
JS中使用sort结合localeCompare实现中文排序实例
2014/07/23 Javascript
EasyUI学习之Combobox下拉列表(1)
2016/12/29 Javascript
bootstrap——bootstrapTable实现隐藏列的示例
2017/01/14 Javascript
Angualrjs 表单验证的两种方式(失去焦点验证和点击提交验证)
2017/05/09 Javascript
Node.js中的不安全跳转如何防御详解
2018/10/21 Javascript
[47:03]完美世界DOTA2联赛PWL S3 access vs LBZS 第一场 12.20
2020/12/23 DOTA
python实现获取客户机上指定文件并传输到服务器的方法
2015/03/16 Python
python实现提取百度搜索结果的方法
2015/05/19 Python
在Lighttpd服务器中运行Django应用的方法
2015/07/22 Python
python如何在列表、字典中筛选数据
2018/03/19 Python
Python实现爬虫设置代理IP和伪装成浏览器的方法分享
2018/05/07 Python
Python实现将Excel转换成xml的方法示例
2018/08/25 Python
python读取dicom图像示例(SimpleITK和dicom包实现)
2020/01/16 Python
用 python 进行微信好友信息分析
2020/11/28 Python
pip 20.3 新版本发布!即将抛弃 Python 2.x(推荐)
2020/12/16 Python
HTML5之SVG 2D入门12—SVG DOM及DOM操作介绍
2013/01/30 HTML / CSS
HTML5超炫酷粒子效果的进度条的实现示例
2019/08/23 HTML / CSS
植物选择:Botanic Choice
2017/02/15 全球购物
EJB需直接实现它的业务接口或Home接口吗,请简述理由
2016/11/23 面试题
完美实现CSS垂直居中的11种方法
2021/03/27 HTML / CSS
积极分子思想汇报
2014/01/04 职场文书
节水倡议书范文
2014/04/15 职场文书
优秀应届毕业生自荐书
2014/06/29 职场文书
党员电教片《信仰》心得体会
2016/01/15 职场文书
js不常见操作运算符总结
2021/11/20 Javascript
利用Python实现Picgo图床工具
2021/11/23 Python
Spring中的@Transactional的工作原理
2022/06/05 Java/Android