以 CGI 模式安装时

章 24. 以 CGI 模式安装时

可能受到的攻击

如果不想把 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_rootuser_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_INFOPATH_TRANSLATED等变量的话,在编译 PHP 解释器时必须加入--enable-discard-path参数。

 

 

文章来源:http://bbs.seuuo.com/html/60/n-1560.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值