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

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';

 

下载源码

打赏此文

如果您觉得本站的内容对您有所帮助,您可以扫描下面的二维码小额支付请我喝杯茶,感谢!打赏记录
支付宝
微信
承诺:凡打赏捐助的朋友,留言备注自己的邮箱,在打赏捐助时间点的6个月内,本站会每周邮件推送原创专业技术博文,供大家学习和参考!

4 条评论

  1. mrxn说道:

    学习了

    博主 国庆快乐啊!!!

  2. wangyan说道:

    大哥 可不可以在网站上分享一下php 的学习视频之类的啊?

    • 23摄氏度说道:

      正在考虑做一些视频资料,国庆之后可能会上线,谢谢你的建议,欢迎关注!

留下评论

All fields marked (*) are required