安全问题

PHP是一种强大语言和解析器,可以作为一个模块包含在web server中或作为CGI程序来执行,它可以存取文件,执行命令和打开服务器上的网络连接。所有这些特性使得任何运行在web server上的东西变的不安全。 PHP被设计成一种比Perl或C安全得多的CGI程序设计语言, 通过正确选择compile-time和 runtime的配置选项,你可以自由的组合出你所需的安全性。

因为有多种途径使用PHP,也就有了许多种配置选项来控制它。 一大堆的选项,保证你能将PHP用于很多目的, 但这也同时意味着这些选项的组合和服务器的设置可能导致不安全的结果。这一章说明了不同的配置项的组合和它们能被安全应用的场合。

CGI binary

可能的攻击

由于某些原因将PHP安装成一个CGI程序,而不做为web server的模块是setup时的一个选项(象 Apache),或者也可以将PHP和不同类型的CGI捆绑起来以建立安全的chroot和script的setuid环境。这种设置中通常PHP的可执行部分放到web server的cgi-bin目录。CERT 建议标准 CA-96.11 再次建议将任何的解析器放到cgi-bin下。PHP程序包甚至可以作为一个独立的解析器,它被设计得能防止下面的入侵:

Case 1: 只对public文件服务

如果你的服务器每个目录都有口令保护或IP存取限制,这部分的设置就不需要了。如果你的web server不允许你重定向, 或者没办法通知PHP程序某个特定的请求是安全的重定向请求,你可以用 --disable-force-cgi-redirect 参数来配置你的script程序。你还得确保你的PHP script程序没有其他变通办法调用,既不能直接用 http://my.host/cgi-bin/php/dir/script.php3 ,也不能用 http://my.host/dir/script.php3重定向。

重定向功能可以配置,例如在apache可以用AddHandler和Action指令设置 (见下).

Case 2: 使用 --enable-force-cgi-redirect

compile-time选项阻止任何人利用类似http://my.host/cgi-bin/php/secretdir/script.php3的方法直接调用PHP。取而代之的是,这种模式下PHP仅仅分析该请求是否通过了web server的重定向法则。

通常在Apache的配置中重定向的指令这样写:

Action php3-script /cgi-bin/php
AddHandler php3-script .php3

此功能仅在Apache web server下测试通过, 并且要将Apache非标准CGI环境变量REDIRECT_STATUS设置为 redirected requests。如果你的web server没有提供任何方法以区分请求是直接请求还是间接请求的话,你就不能使用这个功能,要改用这里讲的其他运行CGI版本的方法。

Case 3: 设置 doc_root 或 user_dir

把现行的内容, 象script和可执行程序放到web server的document目录,被认为是不安全的做法。如果有一些配置错误使得script没有执行,被显示成通常的HTML文档,将导致技术秘密或安全信息(如密码)的泄露。为此一些系统管理员宁愿给script程序单独开设另一个只允许PHP CGI存取的目录,并且不显示任何上面错误的信息。

和上部分一样,如果你的web server没有提供任何方法以区分请求是直接请求还是间接请求的话,就需要给script设置一个不同于web document root的目录doc_root。

你可以通过php3.ini文件中的配置指令 doc_root 来规定PHP script程序的根目录,当然设置环境变量PHP_DOCUMENT_ROOT也可以。如果做了设置, CGI版本的PHP将把请求中的路径信息和doc_root合成起来形成完整的文件路径,因此你可以放心此目录以外没有任何script程序能被执行(使用下面user_dir 的除外).

在此另一个可用选项是 user_dir。当没设置user_dir时,被控制文件读取的是doc_root。如http://my.host/~user/doc.php3这个URL,没有打开用户宿主目录下的文件, 而是打开了doc_root目录下一个叫~user/doc.php3 的文件(是一个开始于~ 的目录名).

如果user_dir设成public_php,一个类似http://my.host/~user/doc.php3的请求,将打开用户宿主目录下的public_php目录下的doc.php3 文件。如果用户的宿主目录是/home/user, 则该文件就是 /home/user/public_php/doc.php3.

不管doc_root怎么设置user_dir 都会发生扩展,所以你可以单独控制document目录和用户目录。

Case 4: PHP 放到web树以外的地方

一个比较安全的方法是把PHP程序包放到web树以外的地方。例如放到 /usr/local/bin目录。这仅仅是使你不得不在任何含有PHP程序的文件的第一行放上类似:

#!/usr/local/bin/php

的一句。 你还需要将这个文件设为可执行。这就如同使用#!符号的Perl、sh或任何其他的CGI语言一样。 

为了使PHP正确的处理这里设置的PATH_INFOPATH_TRANSLATED信息, php分析器必须使用--enable-discard-path 配置选项来编译。

Apache 模块

当PHP做为Apache的模块来运行时它继承了Apache的安全设置。任何的文件请求都要经过Apache的严格检查, 只有通过检查的请求才被送往PHP。