PHP函数addslashes和mysql_real_escape_string的区别_php实例

首先:不要使用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,即“参数化查询”)或者任意一款主流的数据库抽象类库。

时间: 2024-08-02 21:20:18

PHP函数addslashes和mysql_real_escape_string的区别_php实例的相关文章

解析php函数method_exists()与is_callable()的区别_php技巧

php函数method_exists() 与is_callable()的区别在哪?在php面相对象设计过程中,往往我们需要在调用某一个方法是否属于某一个类的时候做出判断,常用的方法有 method_exists()和is_callable(),相比之下,is_callable()函数要高级一些,它接受字符串变量形式的方法名作为 第一个参数,如果类方法存在并且可以调用,则返回true.如果要检测类中的方法是否能被调用,可以给函数传递一个数组而不是类的方法名作为参数.数组必须包含对象或类名,以将其作

深入浅析php中sprintf与printf函数的用法及区别_php实例

PHP sprintf() 函数 把百分号(%)符号替换成一个作为参数进行传递的变量: <?php $number = 2; $str = "Shanghai"; $txt = sprintf("There are %u million cars in %s.",$number,$str); echo $txt; ?> 定义和用法 sprintf() 函数把格式化的字符串写入变量中. arg1.arg2.++ 参数将被插入到主字符串中的百分号(%)符号处

详解PHP中strlen和mb_strlen函数的区别_php实例

在PHP里有两个计算字符串个数的函数一个是 strlen,一个是mb_strlen;先来看看手册中的定义strlenstrlen - 获取字符串长度int strlen ( string $string )返回给定的字符串 string 的长度. mb_strlenint mb_strlen ( string $str [, string $encoding ] )返回给定的字符串 string 的长度.encoding参数为字符编码.如果省略,则使用内部字符编码. 这么看除了mb_strlen

PHP中exec函数和shell_exec函数的区别_php实例

这两个函数都是执行Linux命令函数,不同的是获取返回结果不一样,exec只能获取最后一行数据,shell_execu则可以获取全部数据. 假如脚本路径下有如下文件: 复制代码 代码如下: -bash-4.1# ll 总用量 12 -rw-rw-r--. 1 www web 133  7月 16 15:00 a.php -rw-r--r--. 1 lee web  59  2月 29 17:05 b.php -rw-r--r--. 1 lee web  81  3月  8 17:00 c.php

PHP explode()函数的几个应用和implode()函数有什么区别_php实例

explode()函数介绍 explode() 函数可以把字符串分割为数组. 语法:explode(separator,string,limit). 参数 描述 separator 必需.规定在哪里分割字符串. string 必需.要分割的字符串. limit 可选.规定所返回的数组元素的数目. 可能的值: 大于 0 - 返回包含最多 limit 个元素的数组 小于 0 - 返回包含除了最后的 -limit 个元素以外的所有元素的数组 0 - 返回包含一个元素的数组 本函数返回由字符串组成的数组

php合并数组array_merge函数运算符加号与的区别_php技巧

array_merge在参考手册中的说明如下: array_merge() 将两个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面.返回作为结果的数组. 如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值.然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面. 两个的区别是: 1.数组键名为数字键名时,要合并的两个数组中有同名数字KEY的时候,使用array_merge()不会覆盖掉原来的值,而使用"+"合并数组则会把最先出现的值作为最终

浅析PHP中strlen和mb_strlen的区别_php实例

在PHP中,strlen与mb_strlen是求字符串长度的函数,但是对于一些初学者来说,如果不看手册,也许不太清楚其中的区别. 下面通过例子,讲解这两者之间的区别. 先看例子: <?php //测试时文件的编码方式要是UTF8 $str='中文a字1符'; echo strlen($str).'<br>';//14 echo mb_strlen($str,'utf8').'<br>';//6 echo mb_strlen($str,'gbk').'<br>';/

浅谈php中urlencode与rawurlencode的区别_php实例

前段时间说自己遇到了个<URL加号引发错误>的BUG,引起这个bug的原因就是自己在URL中使用了 urlencode 函数,该函数会把空格转换成加号,这样就导致URL解析出错,而空格只有转换成 %20 才可以可以正常解析,这时我们就需要使用 rawurlencode 函数. 下面就介绍一下 urlencode 函数与 rawurlencode 函数的区别: urlencode 函数: 返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格

PHP中empty和isset对于参数结构的判断及empty()和isset()的区别_php实例

废话不多说了,直接给大家贴代码了. <?php class test{} $a1 = null; $a2 = ""; //$a3 = $a4 = 0; $a5 = '0'; $a6 = false; $a7 = array(); //var $a8; $a9 = new test(); for ($i=1; $i <=9 ; $i++) { $s = 'a'.$i; echo $i . ":"; var_dump(isset($$s)); echo '&