首页 > 开发 > PHP > 正文

PHP程序漏洞产生的原因和防范方法

2024-05-04 22:53:38
字体:
来源:转载
供稿:网友
    滥用include

  1.漏洞原因:

  include是编写php网站中最常用的函数,并且支持相对路径。有很多php脚本直接把某输入变量作为include的参数,造成任意引用脚本、绝对路径泄露等漏洞。看以下代码:

...
$includepage=$_get["includepage"];
include($includepage);
...


  很明显,我们只需要提交不同的includepage变量就可以获得想要的页面。如果提交一个不存在的页面,就可以使php脚本发生错误而泄露实际绝对路径(这个问题的解决办法在下面的文章有说明)。

  2.漏洞解决:

  这个漏洞的解决很简单,就是先判断页面是否存在再进行include。或者更严格地,使用数组对可include的文件作出规定。看以下代码:

$pagelist=array("test1.php","test2.php","test3.php"); //这里规定可进行include的文件
if(isset($_get["includepage"])) //判断是否有$includepage
{
 $includepage=$_get["includepage"];
 foreach($pagelist as $prepage)
 {
  if($includepage==$prepage) //检查文件是否在允许列表中
  {
   include($prepage);
   $checkfind=true;
   break;
  }
 }
 if($checkfind==true){ unset($checkfind); }
 else{ die("无效引用页!"); }
}


  这样就可以很好地解决问题了。

  小提示:有此问题的函数还有:require(),require_once(),include_once(),readfile()等,在编写的时候也要注意。

  未对输入变量进行过滤

  1.漏洞原因:

  这个漏洞早在asp中出现过,当时造成的注入漏洞不计其数。但由于php在当时的影响力较小,所以没有太多的人能够注意这点。对于php来说,这个漏洞的影响性比asp更大,因为有比较多的php脚本使用到文本型数据库。当然也存在sql语句的注入问题。举个比较经典的例子,首先是数据库的:

$id=$_get["id"];

$query="select * from my_table where id='".$id."'"; //很经典的sql注入漏洞
$result=mysql_query($query);


  这里很明显我们可以用注入来获得数据库的其它内容了。这里就不再详细叙述,和asp注入一样的,大家可以看看以前的黑防。然后我们看文本数据库的问题:

$text1=$_post["text1"];
$text2=$_post["text2"];
$text3=$_post["text3"];

$fd=fopen("test.php","a");
fwrite($fd,"/r/n$text1&line;$text2&line;$text3");
fclose($fd);


  文本的漏洞可以说是更加严重。倘若我们的提交的变量中插入一段很小的php代码,就可以另这个文本数据库test.php变成php后门。甚至插入上传代码,让我们可以上传一个完善的php后门。接着提升权限,服务器就是你的了。

  2.漏洞解决:

  这个漏洞的解决方法其实很简单,就是严格对全部提交的变量进行过滤。对一些敏感的字符进行替换。我们可以借助php提供的htmlspecialchars()函数来替换html的内容。这里给出一段例子:

//构造过滤函数
function flt_tags($text)
{
 $badwords=array("操你妈","fuck"); //词汇过滤列表
 $text=rtrim($text);
 foreach($badwords as $badword) //这里进行词汇的过滤
 {
  if(stristr($text,$badword)==true){ die("错误:你提交的内容含有敏感字眼,请不要提交敏感内容。"); }
 }
 $text=htmlspecialchars($text); //html替换
 //这两行把回车替换为

 $text=str_replace("/r"," ",$text);
 $text=str_replace("/n","",$text);
 $text=str_replace("&line;","│",$text); //文本数据库分隔符"&line;"替换为全角的"│"
 $text=preg_replace("//s{ 2 }/"," ",$text); //空格替换
 $text=preg_replace("//t/"," ",$text); //还是空格替换
 if(get_magic_quotes_gpc()){ $text=stripslashes($text); } //如果magic_quotes开启,则进行/'的替换
 return $text;
}

$text1=$_post["text1"];
$text2=$_post["text2"];
$text3=$_post["text3"];

//过滤全部输入
$text1=flt_tags($text1);
$text2=flt_tags($text2);
$text3=flt_tags($text3);

$fd=fopen("test.php","a");
fwrite($fd,"/r/n$text1&line;$text2&line;$text3");
fclose($fd);


  经过一番替换和过滤后,你就可以安全地把数据写入文本或数据库了。

国内最大的酷站演示中心!
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表