PHP函数 addslashes() 和 mysql_real_escape_string() 的区别,SQL注入攻击分析

Posted 52PHP

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP函数 addslashes() 和 mysql_real_escape_string() 的区别,SQL注入攻击分析相关的知识,希望对你有一定的参考价值。

首先:不要使用 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后面跟着0x27(‘),同时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
header(‘Content-Type: text/html; charset=gbk‘);
$mysql = array();
$db = mysqli_init();
$db->real_connect(‘localhost‘, ‘root‘, ‘root‘, ‘go-study‘);

/* SQL注入示例 */
$_POST[‘username‘] = chr(0xbf) . chr(0x27) . ‘ 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‘]}‘";

write2($sql);

$result = $db->query($sql);

if ($result->num_rows) {
	/* 成功 */
} else {
	/* 失败 */
}

尽管使用了addslashes(),我还是可以在不知道用户名和密码的情况下成功登录。我可以轻松的利用这个漏洞进行SQL注入。

要以免这种漏洞,使用 mysql_real_escape_string()、准备语句(Prepared Statements,即“参数化查询”)或者任意一款主流的数据库抽象类库。

以上是关于PHP函数 addslashes() 和 mysql_real_escape_string() 的区别,SQL注入攻击分析的主要内容,如果未能解决你的问题,请参考以下文章

PHP函数 addslashes() 和 mysql_real_escape_string() 的区别,SQL注入攻击分析

php 函数

PHP 5.4 已废弃 magic_quotes_gpc,PHP安全转义函数详解(addslashes htmlspecialcharshtmlentitiesmysql_real_escape

防止sql注入的函数addslashes()

魔术引号addslashes和mysql_real_escape_string的防御以及绕过

树枝上的任何{addslashes}功能?