您的位置:首页 > 数据库

【代码实现】防止SQL注入解决办法

2014-10-01 22:28 627 查看
文章来源:PHP开发学习门户

地址:http://www.phpthinking.com/archives/494

SQL注入是我们在程序开发过程中经常要注意的问题,属于发生于应用程序之数据库层的安全漏洞,通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏。

这是一个简单的数据表:

CREATE TABLE `user` (

`id` int(10) NOT NULL AUTO_INCREMENT,

`name` varchar(50) NOT NULL,

`password` varchar(50) NOT NULL,

`age` smallint(3) NOT NULL,

`is_admin` tinyint(1) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES (’1′, ‘tom’, ’2313sdf’, ’10′, ’0′);

INSERT INTO `user` VALUES (’2′, ‘lucy’, ‘sdff234′, ’5′, ’0′);

INSERT INTO `user` VALUES (’3′, ‘teacher wang’, ‘salfdjlkvjaldf’, ’24′, ’1′);

请看下面这些sql语句:

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

情况一:

若用户通过表单提交的信息是:

$name = “tom’ or ’1′=’1″;

$password = “test”;

数据在未经检验处理的情况下,导致原本的SQL字符串被解析为:

SELECT * from user WHERE name=’tom’ or ’1′=’1′ and password=’test’;

sql执行结果为:

我们在没有输出正确密码的情况下,拿到了“tom”的信息,即用“tom”的身份登录了网站。

情况二:

若用户通过表单提交的信息是:

$name = “‘ or name!=” and is_admin=1 or ’1′=’1″;

$password = “test”;

数据在未经检验处理的情况下,导致原本的SQL字符串被解析为:

SELECT * from user WHERE name=” or name!=” and is_admin=1 or ’1′=’1′ and password=’test’;

sql执行结果为:

我们在没有输出正确用户名及密码的情况下,拿到了“teacher wang”的信息,即用“teacher wang”的身份登录了网站。

情况三:

若用户通过表单提交的信息是:

$name = “‘ ; DELETE FROM user;’”;

$password = “test”;

数据在未经检验处理的情况下,导致原本的SQL字符串被解析为:

SELECT * from user WHERE name=” ; DELETE FROM user;” and password=’test’;

sql执行结果为:

悲剧了,user表数据被清空了

如何防范SQL注入攻击:

在组合SQL字符串时,先针对所传入的参数作字符转义

如果使用PHP开发网页程序的话,亦可打开PHP的Magic quote功能自动将所有的网页传入参数,将单引号字符取代为连续2个单引号字符。

如果可能应该过滤以下字符:分号“;”,两个减号“–”,单引号“’”,注释“/* … */”。

更换危险字符。例如在PHP通过addslashes()函数保护SQL注入。

限制用户输入的长度,限制用户输入的取值范围。

为当前应用建立权限比较小的数据库用户,这样不会导致数据库管理员丢失。

php代码实现:

function mysql_prepare_for_request($value, $type = “string”) {

$return = $value;

switch ($type) {

case “string” :

// 去除斜杠

if (get_magic_quotes_gpc ()) {

$return = stripslashes ( $return );

}

//配置连接有效数据库

$con = mysql_connect ( ‘localhost’, ‘root’, ‘root’ );//填写正确的用户名,密码

if (! $con) {

die ( ‘Could not connect: ‘ . mysql_error () );

}

$return = mysql_real_escape_string ( $return );

mysql_close ( $con );

break;

case “number” :

if (! is_numeric ( $return )) {

$return = 0;

}

break;

default :

$return = “”;

break;

}

return $return;

}

//情况一:用户输入

$name = “tom’ or ’1′=’1″;

$password = “test”;

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “危险:”.$sql.”<br/>”;

//数据转义过滤

$name = mysql_prepare_for_request ( $name, ‘string’ );

$password = mysql_prepare_for_request ( $password, ‘string’ );

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “安全:”.$sql.”<br/><br/>”;

//情况二:用户输入

$name = “‘ or name!=” and is_admin=1 or ’1′=’1″;

$password = “test”;

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “危险:”.$sql.”<br/>”;

//数据转义过滤

$name = mysql_prepare_for_request ( $name, ‘string’ );

$password = mysql_prepare_for_request ( $password, ‘string’ );

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “安全:”.$sql.”<br/><br/>”;

//情况三:用户输入

$name = “‘ ; DELETE FROM user;’”;

$password = “test”;

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “危险:”.$sql.”<br/>”;

//数据转义过滤

$name = mysql_prepare_for_request ( $name, ‘string’ );

$password = mysql_prepare_for_request ( $password, ‘string’ );

$sql=”SELECT * from user WHERE name=’$name’ and password=’$password’;”;

echo “安全:”.$sql.”<br/><br/>”;

输出结果:

危险:SELECT * from user WHERE name=’小明’ or ’1′=’1′ and password=’test’;

安全:SELECT * from user WHERE name=’小明\’ or \’1\’=\’1′ and password=’test’;

危险:SELECT * from user WHERE name=” or name!=” and is_admin=1 or ’1′=’1′ and password=’test’;

安全:SELECT * from user WHERE name=’\’ or name!=\’\’ and is_admin=1 or \’1\’=\’1′ and password=’test’;

危险:SELECT * from user WHERE name=” ; DELETE FROM user;” and password=’test’;

安全:SELECT * from user WHERE name=’\’ ; DELETE FROM user;\” and password=’test’;

下载源码 (点击地址最下面即可)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: