安装为 CGI 程序可能受到的攻击如果您不希望将 PHP 以模块的方式集成到服务器软件(例如 Apache)中,或者希望将 PHP 用于不同的 CGI 外壳来建立安全的 chroot 和 setuid 脚本环境,将 PHP 用作 CGI 程序是安装时的一种选择。这样的安装通常都需要将可执行的 PHP 程序放置到 cgi-bin 目录。CERT 顾问 CA-96.11 的建议反对将任何解释器放入 cgi-bin 目录。尽管 PHP 的可执行程序能够被用作独立的解释器,PHP 的安全机制也能防止由这样的安装所导致的可能的攻击:
方法一:仅就公众文件提供服务如果您的服务器上没有任何不被密码或者基于 IP 访问限制控制的内容,则这些选项配置对您并没有作用。如果您的 WEB 服务器不允许您进行重定向,或者服务器无法和 PHP 程序通信以识别安全的重定向请求,您可以在运行配置脚本的时候使用 --enable-force-cgi-redirect 参数。您还需要确认您的 PHP 脚本不仅仅只依赖某一种方法来调用脚本,不管是直接调用 http://my.host/cgi-bin/php/dir/script.php,还是重定向到 http://my.host/dir/script.php。 在 Apache 中重定向可以使用选项 AddHandler 和 Action 来配置(请参考下文)。 方法二:使用 --enable-force-cgi-redirect 参数该编译时参数防止任何人通过直接访问类似于 http://my.host/cgi-bin/php/secretdir/script.php 的 URL 来调用 PHP。也就是说,只有当脚本基于合法的重定向规则被访问时,PHP 才对它们进行解析。 通常 Apache 的重定向设置是通过以下选项完成的:
该选项仅仅在 Apache WEB 服务器下做过测试,并且依赖 Apache 为被重定向的请求设置非标准的 CGI 环境变量 REDIRECT_STATUS。如果您的 WEB 服务器不支持任何方式以获悉请求是直接的还是被重定向的,您将无法使用该选项。您必须使用本文提及的其它运行 CGI 版本的方法。 方法三:设置 doc_root 或者 user_dir在 WEB 服务器的文档目录中放置诸如脚本和可执行程序等主动的内容,常常被认为是一种不安全的做法。如果由于一些设置的错误,这些脚本没有被执行而像通常的 HTML 文档一样被显示,这将可能导致知识产权或者诸如密码等安全信息的泄漏。因此很多系统管理员宁愿为脚本建立另外一个只能被 PHP CGI 访问的目录结构,使得它们能够被正确解析,又不会出现上述的问题。 同样,如果如前面章节描述的确保请求不被重定向的方法无效,那么我们就有必要建立一个区别于 WEB 文档根目录脚本的 doc_root 目录。 您可以通过配置文件中的选项 doc_root 或者环境变量 PHP_DOCUMENT_ROOT 来设置 PHP 脚本文档的根目录。如果该选项被设置,那么 PHP 的 CGI 版本将总是只通过 doc_root 和请求的路径信息来打开文档,这样您就可以确保脚本不会在该目录以外执行(除了以下将提及的 user_dir 目录)。 另外一个这里可能用得到的选项是 user_dir。如果 user_dir 没有被设置,那么唯一控制被打开的文件名的选项就是 doc_root。打开一个类似于 http://my.host/~user/doc.php 将不会导致打开一个用户主目录中的文件,而是 doc_root 下一个名为 ~user/doc.php 的文件(即一个以波浪号[~]开头的目录名)。 如果 user_dir 被设置为,例如, public_php,那么类似于 http://my.host/~user/doc.php 地请求将打开一个该用户主目录下名为 public_php 的目录下的名为 doc.php 的文件。如果用户的主目录是 /home/user,那么被执行的文件是 /home/user/public_php/doc.php。 user_dir 扩展并不依赖于 doc_root 选项的设定,因此您可以独立控制文档根目录和用户访问目录。 方法四:在 WEB 目录树以外进行 PHP 解析一种安全性非常高的方法是把 PHP 解析程序放置到 WEB 文件目录树以外的某个地方,例如,放置到 /usr/local/bin。这种做法唯一的弊病就是您现在需要在所有含有 PHP 标记符文件的第一行添加类似于以下的内容: 您需要使得这些文件成为可执行文件。也就是说,像对待任何其它 CGI 脚本一样来对待它们。这些 CGI 脚本可能是用 Perl、sh 或者任何其它使用的 #! shell-escape 机制来启动它们自身的脚本语言来编写的。要使这个方法中 PHP 能够正确处理 PATH_INFO 和 PATH_TRANSLATED 信息,在编译 PHP 解析器时必须使用配置参数 --enable-discard-path。 | |||