PHP3中文参考手册 中文翻译:Sadly sadly@21cn.com http://wansoft.soim.net | ||
---|---|---|
上一页 | 第4章配置 | 下一页 |
PHP是一种强大语言和解析器,可以作为一个模块包含在web server中或作为CGI程序来执行,它可以存取文件,执行命令和打开服务器上的网络连接。所有这些特性使得任何运行在web server上的东西变的不安全。 PHP被设计成一种比Perl或C安全得多的CGI程序设计语言, 通过正确选择compile-time和 runtime的配置选项,你可以自由的组合出你所需的安全性。
因为有多种途径使用PHP,也就有了许多种配置选项来控制它。 一大堆的选项,保证你能将PHP用于很多目的, 但这也同时意味着这些选项的组合和服务器的设置可能导致不安全的结果。这一章说明了不同的配置项的组合和它们能被安全应用的场合。
由于某些原因将PHP安装成一个CGI程序,而不做为web server的模块是setup时的一个选项(象 Apache),或者也可以将PHP和不同类型的CGI捆绑起来以建立安全的chroot和script的setuid环境。这种设置中通常PHP的可执行部分放到web server的cgi-bin目录。CERT 建议标准 CA-96.11 再次建议将任何的解析器放到cgi-bin下。PHP程序包甚至可以作为一个独立的解析器,它被设计得能防止下面的入侵:
在问号后的信息被CGI接口作为命令行参数传递给解析器。通常解析器会打开并在命令行执行做为参数的第一个文件。
当调用一个CGI程序时,PHP将拒绝解析命令行参数。
在PHP程序后的路径信息/secret/doc.html,被CGI接口转换为要打开的文件。通常一些web server 配置指令(例如 Apache的: Action) 重定向这些请求到相应文档,例如http://my.host/secret/script.php3 被送往PHP解析器。通过这种设置,web server首先检查目录/secret的存取权限,然后把该要求重定向到http://my.host/cgi-bin/php/secret/script.php3。不幸的是,如果该请求直接给出重定向后的形式,web server将不对 /secret/script.php3 文件进行任何检查, 而仅检查/cgi-bin/php文件的权限。通过这种方法所有有权访问/cgi-bin/php 目录的人都能访问该web server上的所有文件。
在PHP中, 如果server的document目录有任何存取限制的指令,compile-time配置选项--enable-force-cgi-redirect 和runtime 配置指令 doc_root 和 user_dir 参数能够阻止这种袭击。请看下面对于各种组合的说明。
如果你的服务器每个目录都有口令保护或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指令设置 (见下).
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版本的方法。
把现行的内容, 象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目录和用户目录。
一个比较安全的方法是把PHP程序包放到web树以外的地方。例如放到 /usr/local/bin目录。这仅仅是使你不得不在任何含有PHP程序的文件的第一行放上类似:
#!/usr/local/bin/php
的一句。 你还需要将这个文件设为可执行。这就如同使用#!符号的Perl、sh或任何其他的CGI语言一样。
为了使PHP正确的处理这里设置的PATH_INFO和PATH_TRANSLATED信息, php分析器必须使用--enable-discard-path 配置选项来编译。
当PHP做为Apache的模块来运行时它继承了Apache的安全设置。任何的文件请求都要经过Apache的严格检查, 只有通过检查的请求才被送往PHP。