-
Notifications
You must be signed in to change notification settings - Fork 108
Expand file tree
/
Copy pathcgi-bin.xml
More file actions
202 lines (194 loc) · 9.62 KB
/
cgi-bin.xml
File metadata and controls
202 lines (194 loc) · 9.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 87d3bf2e9ea7da5abbeca3e60ea7cf7abfa6f7f3 Maintainer: lm92 Status: ready -->
<!-- CREDITS: dallas,mowangjuanzi -->
<chapter xml:id="security.cgi-bin" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>以 CGI 模式安装时</title>
<sect1 xml:id="security.cgi-bin.attacks">
<title>可能受到的攻击</title>
<simpara>
如果不想把 PHP 嵌入到服务器端软件(如 Apache)作为一个模块安装的话,可以选择以
<acronym>CGI</acronym> 的模式安装。或者把 PHP 用于不同的 <acronym>CGI</acronym>
封装以便为代码创建安全的 <command>chroot</command> 和 <command>setuid</command>
环境。这种安装方式通常会把 <command>php</command> 的可执行文件安装到 web 服务器的
<filename class="directory">cgi-bin</filename> 目录。CERT 建议书 <link
xlink:href="&url.cert;">CA-96.11</link> 建议不要把任何的解释器放到 <filename
class="directory">cgi-bin</filename> 目录。尽管 <command>php</command>
可以作为一个独立的解释器,但是它的设计使它可以防止下面类型的攻击:
</simpara>
<itemizedlist>
<listitem>
<simpara>
访问系统文件:<filename
role="url">http://my.host/cgi-bin/php?/etc/passwd</filename>
</simpara>
<simpara>
在 URL 请求的问号(<literal>?</literal>)后面的信息会传给 CGI
接口作为命令行的参数。其它的解释器会在命令行中打开并执行第一个参数所指定的文件。
</simpara>
<simpara>
当作为 CGI 二进制文件调用时,<command>php</command> 会拒绝解释命令行参数。
</simpara>
</listitem>
<listitem>
<simpara>
访问服务器上的任意 Web 文档:<filename
role="url">http://my.host/cgi-bin/php/secret/doc.html</filename>
</simpara>
<simpara>
URL 中位于 PHP 二进制名称后面的路径信息 <filename
role="uri">/secret/doc.html</filename>,通常用于指定由 <acronym>CGI</acronym>
程序打开和解释的文件名。通常一些 web 服务器配置指令(Apache:<literal>Action</literal>)用于将 URL
(如 <filename role="url">http://my.host/secret/script.php</filename>)重定向请求到
PHP 解释器。使用此设置,Web 服务器会先检查目录 <filename role="uri">/secret</filename>
的访问权限,然后创建 <filename role="url">http://my.host/cgi-bin/php/secret/script.php</filename>
的重定向请求。不幸的是,如果请求最初是这种形式发出的,那么 Web 服务器不会对文件
<filename role="uri">/secret/script.php</filename> 进行任何访问检查,而只会对
<filename role="uri">/cgi-bin/php</filename> 进行访问检查。
这样任何能访问 <filename role="uri">/cgi-bin/php</filename> 的用户都可以访问
web 服务器上任何受保护的文档。
</simpara>
<simpara>
在 PHP 里,运行时配置指令
<link linkend="ini.cgi.force-redirect">cgi.force_redirect</link>、
<link linkend="ini.doc-root">doc_root</link> 和
<link linkend="ini.user-dir">user_dir</link>
都可以为服务器上的文件和目录添加限制,用于防止这类攻击。下面将对各个选项的设置进行详细讲解。
</simpara>
</listitem>
</itemizedlist>
</sect1>
<sect1 xml:id="security.cgi-bin.default">
<title>情形一:只运行公开的文件</title>
<simpara>
如果 web 服务器中所有内容都受到密码或 IP
地址的访问限制,就不需要设置这些选项。如果
web 服务器不支持重定向,或者 web 服务器不能和 PHP
通信而使访问请求变得更为安全,可以开启
<link linkend="ini.cgi.force-redirect">cgi.force_redirect</link> ini
指令。除此之外,还要确认 PHP 程序不依赖其它方式调用,比如通过直接的
<filename role="php">http://my.host/cgi-bin/php/dir/script.php</filename>
访问或通过重定向访问
<filename role="php">http://my.host/dir/script.php</filename>。
</simpara>
<simpara>
在Apache中,重定向可以使用 <literal>AddHandler</literal> 和 <literal>Action</literal> 语句来设置,请看下一节。
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.force-redirect">
<title>情形二:使用 <literal>cgi.force_redirect</literal></title>
<simpara>
配置指令 <link linkend="ini.cgi.force-redirect">cgi.force_redirect</link>
可以防止任何人通过如
<filename role="php">http://my.host/cgi-bin/php/secretdir/script.php</filename>
这样的 URL 直接调用 <command>php</command>。PHP 在此模式下只会解析已经通过了
web 服务器的重定向规则的 URL。
</simpara>
<simpara>
通常 Apache 中的重定向设置可以通过以下指令完成:
</simpara>
<programlisting role="apache-conf">
<![CDATA[
Action php-script /cgi-bin/php
AddHandler php-script .php
]]>
</programlisting>
<simpara>
此选项只在 Apache 下进行过测试,并且要依赖于 Apache
在重定向操作中所设置的非标准 CGI 环境变量
<envar>REDIRECT_STATUS</envar>。如果 web
服务器不支持任何方式能够判断请求是直接的还是重定向的,就不能使用这个选项,而应该用其它方法。请看下一节。
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.doc-root">
<title>情形三:设置 doc_root 或 user_dir</title>
<simpara>
在 web 服务器的主文档目录中包含动态内容如脚本和可执行程序有时被认为是一种不安全的实践。如果因为配置上的错误而未能执行脚本而作为普通
HTML 文档显示,那就可能导致知识产权或密码资料的泄露。所以很多系统管理员都会专门设置一个只能通过
PHP CGI 来访问的目录,这样该目录中的内容只会被解析而不会原样显示出来。
</simpara>
<simpara>
对于前面所说无法判断是否重定向的情况,很有必要在主文档目录之外建立一个专用于脚本的
<link linkend="ini.doc-root">doc_root</link> 目录。
</simpara>
<simpara>
可以通过<link linkend="configuration.file">配置文件</link>内的
<link linkend="ini.doc-root">doc_root</link>
指令或设置环境变量
<envar>PHP_DOCUMENT_ROOT</envar> 来定义 PHP 脚本主目录。如果设置了该项,那么
PHP 的 <acronym>CGI</acronym> 版本就只会解释 <parameter>doc_root</parameter>
目录下的文件,并确保目录外的脚本不会被 PHP
解释器执行(下面所说的 <parameter>user_dir</parameter> 除外)。
</simpara>
<simpara>
另一个可用的选项就是
<link linkend="ini.user-dir">user_dir</link>。当 <parameter>user_dir</parameter>
没有设置的时候,<parameter>doc_root</parameter>
就是唯一能控制在哪里打开文件的选项。访问如
<filename role="url">http://my.host/~user/doc.php</filename>
这个 URL 时,并不会打开用户主目录下文件,而只会执行
<parameter>doc_root</parameter> 目录下的
<filename role="uri">~user/doc.php</filename>(这个子目录以
[<literal>~</literal>] 作开头)。
</simpara>
<simpara>
如果设置了 <parameter>user_dir</parameter>,例如
<filename role="dir">public_php</filename>,那么像
<filename role="url">http://my.host/~user/doc.php</filename>
这样的请求将会执行用户主目录下的
<filename role="dir">public_php</filename> 子目录下的
<filename>doc.php</filename> 文件。假设用户主目录的绝对路径是
<filename role="dir">/home/user</filename>,那么被执行文件将会是
<filename>/home/user/public_php/doc.php</filename>。
</simpara>
<simpara>
<parameter>user_dir</parameter> 的设置与
<parameter>doc_root</parameter> 无关,所以可以分别控制
PHP 脚本的主目录和用户目录。
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.shell">
<title>情形四:PHP 解释器放在 web 目录以外</title>
<para>
一个非常安全的做法就是把 PHP 解释器放在 web 目录外的地方,比如说
<filename role="dir">/usr/local/bin</filename>。这样做唯一不便的地方就是必须在每一个包含
PHP 代码的文件的第一行加入如下语句:
<informalexample>
<programlisting>
<![CDATA[
#!/usr/local/bin/php
]]>
</programlisting>
</informalexample>
还要将这些文件的属性改成可执行。也就是说,要像处理用
Perl 或 sh 或其它任何脚本语言写的 CGI 脚本一样,使用以 <literal>#!</literal>
开头的 shell-escape 机制来启动它们。
</para>
<para>
要使 PHP 能使用此设置正确处理
<envar>PATH_INFO</envar> 和 <envar>PATH_TRANSLATED</envar>
信息,需要开启
<link linkend="ini.cgi.discard-path">cgi.discard_path</link> ini 指令。
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->