如何防范二次漏洞
>首页 -> 社会专题 -> 硬件网络 2010-07-08 来源:csdn 作者:phphot 【】 浏览:904

本文主要针对PHP对MySQL的操作简单提出产生二次漏洞的原因,以及防范方案。

一、提出问题

众所周知,数据库操作中对于一些特殊字符(例如单引号“'”、反斜线“/”等元字符)有着严格的限制,如果向数据库中写入的数据含有这样的特殊字符,操作将会带来不安全因素。所以对于用户输入的数据,我们完全认为它是没有安全性的,需要在程序中对其进行适当的过滤处理后,方可写入数据库。

对于这点,相信大多数PHP程序员都会注意到,一般采取的方法是使用AddSlashes()字符串函数对用户输入的数据进行处理,把数据中的特殊字符加上反斜线进行转译。这样对于一般的数据库写入是正常的,并不会带来什么问题,而问题来源于之后的取出操作。对于前面用AddSlashes()函数进行转译后保存在数据库中的数据,经过查看数据库我们发现里面存储的是原始的数据,也就是说其中的特殊字符并没有被加上反斜线。此时当数据来源于这时的数据库本身时,安全问题仍然存在,这就造成了二次漏洞。

流程描述 原始的数据,如“'”=> 程序处理(安全的数据如“/'” )=> MySQL里存

储(原始的数据如“'”) => 程序处理(处理的是“'”)=> 产生危险

二、分析问题

因此在进行数据过滤的时候,不要只是暂时地让数据失去危害,可以考虑永久地让数据失去危害,譬如在过滤的时候不是将“'”变成“/'”等,而是在条件允许的情况下将其直接转换成HTML字符“'”,这样并不影响显示但是数据却不再会包含让数据库的元字符,所以不用担心注入漏洞了,其他的字符可以一样考虑处理。

三、解决问题

为解决此问题,我们可以用str_replace()函数依次对必要的特殊字符进行替换。此时要注意替换后的字符串长度将会改变,每替换一个字符,字符串长度将会增加5。我们还需在写入数据库之前判断它是否超过字段大小。

五、演示代码

File:test.php 代码:

<?php

/*

*   二次漏洞简单检测

*   Author Linvo

*   Build 2007-11-8

*/

/*

*   链接数据库(根据情况自己修改)

*/

$Host = 'localhost';

$User = 'root';

$Pass = 'password';

$DB = 'test'; //测试库名

$db = @mysql_connect($Host,$User,$Pass);

if(!$db)    die("连接服务器MySQL出错!");

else    if(!mysql_select_db($DB,$db))   die("连接数据库出错!");

define(INPUT_MAX_LENGTH, 10);   //前台maxlength值(初步检测)

define(INDB_MAX_LENGTH, 20);    //数据库中字段设置的大小值(用于写入前的必要安全测试)

/*

*   原始数据(如用户输入等)

*/

$string = "’//"; //用户输入内容

if(strlen($string) > INPUT_MAX_LENGTH) //初步检测

die("输入内容超长");

echo "输入的内容:".$string;

/*

*   过滤方案

*/

//$string_in1 = AddSlashes($string); //方案一:临时失去危险,但有二次漏洞

$string_in1 = str_slashes($string); //方案二:永久性失去危险!(自定义函数)

/*

*   安全测试

*/

$string_in2 = test_db($string_in1, 1); //一次漏洞检测

$string_in3 = test_db($string_in2, 2); //二次漏洞检测

/*

*   数据库操作(函数)

*/

function test_db($str_in, $time)

{

echo "第 $time 次要写入的内容:".$str_in;

if(strlen($str_in) > INDB_MAX_LENGTH) die("第 $time 次写入数据超长!");//必要安全测试!

$result = mysql_query("INSERT INTO str(str) VALUES('$str_in')"); //写入

if(!$result)

{

die("<font color=red>第 $time 次写入数据库失败</font>");

}

echo "第 $time 次写入完毕";

$result = mysql_query("SELECT str FROM str ORDER BY id DESC LIMIT 1");//取出

if($item = mysql_fetch_array($result))

{

$str_out = $item['str'];

}

echo "第 $time 次输出:".$str_out."";

return $str_out;

}

/*

*   永久性过滤危险字符

*/

function str_slashes($str)

{

$str = str_replace("'","'",$str); //转译 '

$str = str_replace("//","/",$str); //转译 /

return $str;

}

?>

您看到此篇文章时的感受是:
Tags: 责任编辑:佚名
免责申明: 除原创及很少部分因网文图片遗失而补存外,本站不存储任何有版权的内容。你看到的文章和信息及网址索引均由机器采集自互联网,由于时间不同,内容可能完全不同,请勿拿本网内容及网址索引用于交易及作为事实依据,仅限参考,不会自行判断者请勿接受本站信息,本网转载,并不意味着赞同其观点或证实其内容的真实性.如涉及版权等问题,请立即联系管理员,我们会予以更改或删除,保证您的权利.对使用本网站信息和服务所引起的后果,本网站不作任何承诺.
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论:0条】 【关闭】 【返回顶部
更多
上一篇对Google App Engine安全思考 下一篇关闭Win2003/2008中IE增强的安全..
密码: (新用户注册)

最新文章

图片主题

热门文章

推荐文章

相关文章

便民服务

手机扫描

空间赞助

快速互动

论坛互动
讨论留言

有事联系

有哪个那个什么的,赶紧点这里给DOVE发消息

统计联系

MAIL:gnlt@Dovechina.com
正在线上:

版权与建议

任何你想说的