PHP编程中的常见漏洞和代码实例(3)

正如我们前面讨论的那样,include()和require()主要是为了支持代码库,因为我们一般是把一些经常使用的函数放到一个独立的文件中,这个独立的文件就是代码库,当需要使用其中的函数时,我们只要把这个代码库包含到当前的文件中就可以了。

最初,人们开发和发布PHP程序的时候,为了区别代码库和主程序代码,一般是为代码库文件设置一个".inc"的扩展名,但是他们很快发现这是一个错误,因为这样的文件无法被PHP解释器正确解析为PHP代码。如果我们直接请求服务器上的这种文件时,我们就会得到该文件的源代码,这是因为当把PHP作为 Apache的模块使用时,PHP解释器是根据文件的扩展名来决定是否解析为PHP代码的。扩展名是站点管理员指定的,一般是".php", ".php3"和".php4"。如果重要的配置数据被包含在没有合适的扩展名的PHP文件中,那么远程攻击者很容易得到这些信息。

最简单的解决方法就是:给每个文件都指定一个PHP文件的扩展名,这样可以很好的防止泄露源代码的问题,但是又产生了新的问题,通过请求这个文件,攻击者可能使本该在上下文环境中运行的代码独立运行,这可能导致前面讨论的全部攻击。

下面是一个很明显的例子:

复制代码 代码如下:


 In main.php:  
 <?php  
 $libDir = "/libdir";  
 $langDir = "$libdir/languages";  
 ...  
 include("$libdir/loadlanguage.php":  
 ?>  

In libdir/loadlanguage.php:  
 <?php  
 ...  
  
 include("$langDir/$userLang");  
 ?>   

当"libdir/loadlanguage.php"被"main.php"调用时是相当安全的,但是因为"libdir /loadlanguage"具有".php"的扩展名,因此远程攻击者可以直接请求这个文件,并且可以任意指定"$langDir" 和"$userLang"的值。

如何通过Session文件进行攻击?

PHP 4或更新的版本提供了对sessions的支持,它的主要作用是在PHP程序中保存页与页之间的状态信息。例如,当一个用户登陆进入网站,他登陆了的这个事实以及谁登陆进入这个网站的相关信息都将被保存在session中,当他在网站中到处浏览时,所有的PHP代码都可以获得这些状态信息。

事实上,当一个session启动时(实际上是在配置文件中设置为在第一次请求时自动启动),就会生成一个随机的"session id",如果远程浏览器总是在发送请求时提交这个"session id"的话,session就会一直保持。这通过Cookie很容易实现,也可以通过在每页提交一个表单变量(包含"session id")来实现。PHP程序可以用session注册一个特殊的变量,它的值会在每个PHP脚本结束后存在session文件中,也会在每个PHP脚本开始前加载到变量中。下面是一个简单的例子:

复制代码 代码如下:


<?php  
session_destroy(); // Kill any data currently in the session  
$session_auth = "shaun";  
session_register("session_auth"); // Register $session_auth as a session variable  
?>   

新版本的PHP都会自动把"$session_auth"的值设置为"shaun",如果它们被修改的话,以后的脚本都会自动接受修改后的值,这对无状态的Web来说的确是种很不错的工具,但是我们也应该小心。

一个很明显的问题就是确保变量的确来自session,例如,给定上面的代码,如果后续的脚本是下面这样的话:

复制代码 代码如下:


<?php  
if (!emptyempty($session_auth))  
// Grant access to site here  
?>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/a321fa8ea3f6664993d734109e24a0e9.html