1
0
mirror of https://github.com/php/doc-ja.git synced 2026-03-23 22:52:11 +01:00
Files
archived-doc-ja/security/cgi-bin.xml
2026-02-24 23:42:11 +09:00

256 lines
13 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 87d3bf2e9ea7da5abbeca3e60ea7cf7abfa6f7f3 Maintainer: hirokawa Status: ready -->
<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 を <acronym>CGI</acronym> バイナリとして使用するのは、PHP を
モジュールとして(Apache のような)サーバーソフトウエアに組み込み
たくない何らかの理由がある場合や安全な chroot と setuid 環境をス
クリプトに提供する他の <acronym>CGI</acronym> ラッパーと組み合わせて PHP を使用する
場合の設定オプションです。セットアップ時には、通常、
<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>
バイナリをスタンドアロンのインタプリタとして使用することが
できる場合でも、PHP は、セットアップにより生じる可能性がある
次のような攻撃を防ぐように設計されています。
</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> プログラムによりオープンされて実行される
ファイルの名前を指定するために従来より使用されています。
<filename role="url">http://my.host/secret/script.php</filename>
のようなドキュメントへの要求を PHP インタプリタにリダイレクト
するために、通常、何らかの Web サーバー設定用命令(Apache では <literal>Action</literal>)
が使用されます。この設定により、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>ケース 1: 配布制限がないファイルのみを配布</title>
<simpara>
サーバー上にパスワードまたは IP アドレスを元にしたアクセス制限に
よる制約を課すコンテンツがない場合、この設定オプションを使用す
る必要はありません。使用する Web サーバーがリダイレクトを許可しな
い場合やサーバーがリダイレクト要求を安全に処理しつつPHP バイナリ
と通信できる手段を有していない場合、ini ディレクティブ
<link linkend="ini.cgi.force-redirect">cgi.force_redirect</link> を有効にできます。
この場合でも、直接
的な方法 <filename
role="php">http://my.host/cgi-bin/php/dir/script.php</filename>
でもなくリダイレクション <filename
role="php">http://my.host/dir/script.php</filename>でもない他の
やり方で PHP スクリプトを呼び出せるようになっていないかどうか確認
する必要があります。
</simpara>
<simpara>
リダイレクションは、例えば Apache では命令 <literal>AddHandler</literal>
および <literal>Action</literal> で設定することができます。(以下を参照ください。)
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.force-redirect">
<title>ケース 2: <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> を呼び出すことを禁止します。
代わりに、
Web サーバーのリダイレクションにより処理された場合は、
PHP はこのモードでのみ処理を行います。
</simpara>
<simpara>
通常、Apache 用設定でのリダイレクションは、
次の命令を使用して行います。</simpara>
<programlisting role="apache-conf">
<![CDATA[
Action php-script /cgi-bin/php
AddHandler php-script .php
]]>
</programlisting>
<simpara>
このオプションは、Apache Web サーバーでのみテストされており、リク
エストのリダイレクト時に Apache が標準ではないCGI 環境変数
<envar>REDIRECT_STATUS</envar> をセットすることを前提にしています。
リクエストが直接のものであるか間接のものであるかを示す手段をWeb
サーバーが全くサポートしていない場合は、このオプションを使用する
ことはできません。この場合、ここで記した CGI 版を実行する他の方法
の内の一つを使用する必要があります。
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.doc-root">
<title>ケース 3: doc_root または user_dir を設定</title>
<simpara>
Web サーバー上のドキュメントディレクトリに
スクリプトや実行ファイルのようなアクティブな内容を読み込むのは、
往々にして危険な行為であるとみなされることがあります。
何らかの設定ミスによりスクリプトが実行されず、通常の HTML ドキュメント
として表示されてしまう場合には、知的著作物またはパスワードのような
セキュリティ情報が漏洩する可能性があります。
このため、多くのシステム管理者は、スクリプトを PHP CGI を通じてのみ
アクセス可能な他のディレクトリ構造にセットアップしたいと思うこと
でしょう。
この場合、常にインタープリタに処理されるため、上記のように表示されること
はありません。
</simpara>
<simpara>
前節で記したようなリクエストがリダイレクトされたものでないことを
確かめる方法が利用可能でない場合、
スクリプト用の <link linkend="ini.doc-root">doc_root</link> を Web ドキュメント用ルートとは別に
セットアップする必要があります。
</simpara>
<simpara>
設定用命令 <link linkend="ini.doc-root">doc_root</link> により
<link linkend="configuration.file">設定ファイル</link> ファイル中で
PHP スクリプト用ドキュメントルートを設定することができます。
または、環境変数 <envar>PHP_DOCUMENT_ROOT</envar> でも設定する
ことができます。
これを設定した場合、<acronym>CGI</acronym> 版の PHP は、
常に開くファイルの名前をこの <parameter>doc_root</parameter>
リクエストのパス情報を用いて作成し、
(以下の <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>user_dir</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>
ようなリクエストは、そのユーザー user のホームディレクトリにある
<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> の設定によらず行われます。
このため、ドキュメントルートおよびユーザーディレクトリへの
アクセスを別々に制御することができます。
</simpara>
</sect1>
<sect1 xml:id="security.cgi-bin.shell">
<title>ケース 4: Webツリーの外にPHPパーサーを置く</title>
<para>
非常に安全性の高いオプションとしてPHP パーサーのバイナリをファイル
用 Web ツリーの外側、例えば <filename
role="dir">/usr/local/bin</filename>に置くことが考えられます。こ
のオプションの唯一の欠点は、PHP タグを有する全てのファイルの先頭
行に次のような一行を加える必要があることです。
<informalexample>
<programlisting>
<![CDATA[
#!/usr/local/bin/php
]]>
</programlisting>
</informalexample>
また、ファイルを実行可能にしておく必要があります。この場合、実行
時にシェルエスケープ機能 <literal>#!</literal> を使用する Perl や
sh や他のスクリプト言語で書かれた CGI スクリプトを処理するのと全
く同様に処理を行います。
</para>
<para>
この設定で <envar>PATH_INFO</envar> および
<envar>PATH_TRANSLATED</envar> 情報を正しく処理するためには、
ini ディレクティブ
<link linkend="ini.cgi.discard-path">cgi.discard_path</link> を有効にする必要があります。
</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
-->