您的位置:首页 > 编程语言 > PHP开发

$_SERVER['PHP_SELF']漏洞知多少

2012-06-18 21:40 169 查看
$_SERVER['PHP_SELF']是PHP语言中的“服务器端系统变量”,它的值是“当前php文件相对于网站根目录的位置地址”。举例说明,如果在http://www.shuihan.com/output/html/data.php文件中使用$_SERVER['PHP_SELF'],代码如下:

1echo $_SERVER['PHP_SELF'];
则在浏览器中打开该页输出为:
/output/html/data.php

  正是由于$_SERVER['PHP_SELF']能输出“当前文件相对根目录的位置”,非常好用,所以很多程序员在写程序的时候很喜欢用到它,PHPBB中就使用的这个变量递交查询结果。然而现在我要说的不是他多好用,而是它存在着漏洞,可能被坏人利用,恶意注入代码。

  可能有人会问,既然是服务器端的系统变量,Hacker怎么可能利用呢?这种认识是错误的。对于表单提交页面,Hacker可以通过巧妙地递交查询代码修改$_SERVER['PHP_SELF']的值,从而注入设计好的恶意代码。我们还是看一个例子,下面这个代码在很多程序中广泛使用:(假如该代码所在页面是http://www.shuihan.com/form.php


1<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"><br><!-- My Form --><br></form>
一个有经验的Hacker可能会用下面的地址访问该页面:
http://www.shuihan.com/form.php%22%3E%3Cscript%3Ealert(’XSS attack!’)%3C/script%3E%3Cbr

用上面这句话访问页面,相当于下面的代码:

1<form method="post" action="http://www.shuihan.com/form.php">
2<script>alert('XSS attack!')</script><br /><br><!-- My Form -->
3</form>
  通过上面的演示,现在你是否看到危险性了?(当然上面的演示例子是没有危险的)。经过细心的设计,Hacker可以设计出任何可能的恶意注入查询。

看到了危险的存在,那我们怎么才能避免这个问题呢?或者我们已经在自己的设计中大量的使用了$_SERVER['PHP_SELF'],怎样回避这个漏洞呢?

  网上有很多帖子提及到这个漏洞,但是却没有几个给出具体的解决办法,这里水寒参考了一位外国朋友的解决办法,整理了一下贴出来供大家使用时参考。

1//获取"当前文件名"(form.php)
2$phpself = basename(__FILE__);
3//截取相对路径中的"目录部分"(php不含文件名),然后再在该"目录部分"后面加上"当前文件名"
4//两部分接起来就构成了完整的"当前文件路径",使用该路径就清理掉了恶意代码
5$_SERVER['PHP_SELF'] = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'],
6$phpself)) . $phpself;

当心$_SERVER['PHP_SELF']的安全漏洞

刚刚写的,还得新鲜的,冒着热气呢:

我们在本页处理提交列表单的时候往往习惯于这样写:

<form

action="<?php echo $_SERVER['PHP_SELF']; ?>">

拷贝源代码

看上去没有什么问题,但看看下面的情况你就知道它有多么危险了:

我们假设列表单提交界面的名字为foo.php,放到PHP环境中之后,在地址栏这样输入:

foo.php/%22%3E%3Cscript%3Ealert('xss攻击')%3C/script%3E%3Cfoo

拷贝源代码

会弹出一个JS的alert!很明显这根本就是一次典型的XSS攻击(跨站攻击),理由在于<?php echo $_SERVER['PHP_SELF']; ?>">,直接输出了没有进行任何滤掉的$_SERVER['PHP_SELF'],这个CASE的后果还不严重,如果你把这个变量直接保存到数据库,而别人又写了段JS破坏脚本script(批处理文件)。。。那就不堪设想了。

在手册上是这样解析$_SERVER['PHP_SELF']的:

“PHP_SELF”

当前正在执行脚本script(批处理文件)的文件名,与 document root 相关。举例来说,在 URL 地址为 http://example.com/test.php/foo.bar 的脚本script(批处理文件)中使用 $_SERVER['PHP_SELF'] 将会得到 /test.php/foo.bar 这个结果。__FILE__ 常量包含当前(例如包含)文件的绝对路径和文件名。

拷贝源代码

很明显,$_SERVER['PHP_SELF'] 虽然“看起来”是服务器给予的环境变量,但和 $_POST 与 $_GET 相同,是可以被用户篡改的,如果不进行滤掉的话,谁知道后果有多严重呢?

解决方案很简单,和以前讲过的安全知识相同,使用htmlentities 函数滤掉:

echo htmlentities($_SERVER['PHP_SELF']);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐