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

PHP 安全----以 CGI 模式安装时

2012-02-17 14:01 603 查看

来源:http://www.php.net/manual/zh/security.intro.php

简介

PHP 作为一种强大的语言,无论是以模块还是
CGI 的方式安装,它的解释器都可以在服务器上访问文件、运行命令以及创建网络连接等。这些功能也许会给服务器添加很多不安全因素,但是只要正确地安装和配置 PHP,以及编写安全的代码,那么 PHP 相对于 Perl 和 C 来说,是能创建出更安全的 CGI 程序的。而且,也可以在可用性和安全性之间找到一个很好的平衡点。
PHP 可能会被用在很多不同的方面,因此,PHP 内置的选项以方便用户对其进行配置。虽然众多的选项可以使 PHP 完成很多工作,但是对这些选项的设定以及对服务器的配置很可能会产生安全问题。
PHP 的选项与其语法一样,具有很高的灵活性。使用 PHP,可以在只有 shell 用户权限的环境下创建完善的服务器端程序,或者在被严格限制环境下使用它来完成服务器端包含(Server-Side Includes)而无需承但太大的风险。如何建立这样一种环境,其安全性如何,很大程度上取决于 PHP 的开发者。
本章以一些常规的安全建议作开头,讲述如何在不同的环境下尽可能地提高安全性,以及介绍对于不同安全级别的一些编程原则。

总则

绝对安全的系统是不存在的,因此安全业界常用的方法有助于平衡可用性和风险。对用户提交的每一个变量都进行双重验证可能是一个很负责任的行为,但会导致用户必须花很多时间去填写一张复杂无比的表格,从而迫使某些用户尝试绕过安全机制。
最好的安全机制应该能在不防碍用户,并且不过多地增加开发难度的情况下做到能满足需求。实际上,一些安全问题往往会发生在这种过度强化安全机制的系统上。
不要忘记著名的等强原则:一个系统的的强度是由它最薄弱的环节决定的(译者注:相当于木桶原理)。如果所有的事务都基于时间、地点、事务种类进行详细的记录,而用户验证却只依靠一个 cookie,那么用户所对应的事务记录的可信度就被大大剥弱了。
调试代码的时候一定要记住,就算是一个简单的页面也很难对所有可能发生的情况进行检测:对你不满的雇员不一定会输入如你所愿的东西,黑客也有足够的时间研究你的系统,当然,你的宠物猫也会跳到你的键盘上。这就是为什么必须检查所有的代码,去发现哪里可以引入不正当的数据,然后对代码改进、简化或者增强。
互联网上充满了为了成名而破坏你的代码、攻击你的网站并输入不正当数据的人,总之他们会使你的生活充满乐趣。无论是大网站还是小网站,只要能和互联网连接,就会成为一个目标。很多黑客程序并不理会网站的大小,只会机械地扫描 IP 地址并找寻受害者。我们希望那个不要是你。

以 CGI 模式安装时

Table of Contents

可能受到的攻击
情形一:只运行公开的文件
情形二:使用 --enable-force-cgi-redirect 选项
情形三:设置 doc_root 或 user_dir
情形四:PHP 解释器放在 web 目录以外

可能受到的攻击

如果不想把 PHP 嵌入到服务器端软件(如 Apache)作为一个模块安装的话,可以选择以
CGI 的模式安装。或者把 PHP 用于不同的 CGI 封装以便为代码创建安全的 chroot 和 setuid 环境。这种安装方式通常会把 PHP 的可执行文件安装到 web 服务器的 cgi-bin 目录。CERT 建议书» CA-96.11
建议不要把任何的解释器放到 cgi-bin 目录。尽管 PHP 可以作为一个独立的解释器,但是它的设计使它可以防止下面类型的攻击:

访问系统文件:http://my.host/cgi-bin/php?/etc/passwd在 URL 请求的问号(?)后面的信息会传给 CGI 接口作为命名行的参数。其它的解释器会在命令行中打开并执行第一个参数所指定的文件。但是,以
CGI 模式安装的 PHP 解释器被调用时,它会拒绝解释这些参数。
访问服务器上的任意目录:http://my.host/cgi-bin/php/secret/doc.html好像上面这种情况,PHP 解释器所在目录后面的 URL 信息/secret/doc.html
将会例行地传给CGI 程序并进行解释。通常一些 web 服务器的会将它重定向到页面,如http://my.host/secret/script.php。如果是这样的话,某些服务器会先检查用户访问/secret 目录的权限,然后才会创建http://my.host/cgi-bin/php/secret/script.php
上的页面重定向。不幸的是,很多服务器并没有检查用户访问 /secret/script.php 的权限,只检查了/cgi-bin/php 的权限,这样任何能访问/cgi-bin/php 的用户就可以访问 web 目录下的任意文件了。在 PHP 里,编译时配置选项--enable-force-cgi-redirect
以及运行时配置指令
doc_root 和
user_dir 都可以为服务器上的文件和目录添加限制,用于防止这类攻击。下面将对各个选项的设置进行详细讲解。

情形一:只运行公开的文件

如果 web 服务器中所有内容都受到密码或 IP 地址的访问限制,就不需要设置这些选项。如果 web 服务器不支持重定向,或者 web 服务器不能和 PHP 通信而使访问请求变得更为安全,可以在 configure 脚本中指定--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 在此模式下只会解析已经通过了 web 服务器的重定向规则的 URL。
通常 Apache 中的重定向设置可以通过以下指令完成:

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


此选项只在 Apache 下进行过测试,并且要依赖于 Apache 在重定向操作中所设置的非标准 CGI 环境变量
REDIRECT_STATUS。如果 web 服务器不支持任何方式能够判断请求是直接的还是重定向的,就不能使用这个选项,而应该用其它方法。请看下一节。

情形三:设置 doc_root 或 user_dir

在 web 服务器的主文档目录中包含动态内容如脚本和可执行程序有时被认为是一种不安全的实践。如果因为配置上的错误而未能执行脚本而作为普通 HTML 文档显示,那就可能导致知识产权或密码资料的泄露。所以很多系统管理员都会专门设置一个只能通过 PHP CGI 来访问的目录,这样该目录中的内容只会被解析而不会原样显示出来。
对于前面所说无法判断是否重定向的情况,很有必要在主文档目录之外建立一个专用于脚本的 doc_root 目录。
可以通过配置文件内的doc_root 或设置环境变量PHP_DOCUMENT_ROOT 来定义 PHP
脚本主目录。如果设置了该项,那么 PHP 就只会解释 doc_root 目录下的文件,并确保目录外的脚本不会被 PHP 解释器执行(下面所说的user_dir 除外)。
另一个可用的选项就是
user_dir。当 user_dir 没有设置的时候,doc_root 就是唯一能控制在哪里打开文件的选项。访问如http://my.host/~user/doc.php 这个 URL 时,并不会打开用户主目录下文件,而只会执行 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 无关,所以可以分别控制 PHP 脚本的主目录和用户目录。

情形四:PHP 解释器放在 web 目录以外

一个非常安全的做法就是把 PHP 解释器放在 web 目录外的地方,比如说 /usr/local/bin。这样做唯一不便的地方就是必须在每一个包含 PHP 代码的文件的第一行加入如下语句:

#!/usr/local/bin/php


还要将这些文件的属性改成可执行。也就是说,要像处理用 Perl 或 sh 或其它任何脚本语言写的 CGI 脚本一样,使用以 #! 开头的 shell-escape 机制来启动它们。
在这种情况下,要使 PHP 能正确处理 PATH_INFO 和
PATH_TRANSLATED 等变量的话,在编译 PHP 解释器时必须加入
--enable-discard-path 参数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: