safe_mode 関数は PHP5.3 より前のバージョンで利用可能になりますが、デフォルトの状態では、safe_mode セーフティモードがオフになっています。safe_mode をオンにする詳細とシステムへの影響を紹介します。
PHP セーフ モードを有効にする (PHP5.3 にはセーフ モードがなくなることに注意してください)
PHP のセーフ モードをオンまたはオフにするには、php.ini のsafe_mode オプションを使用します。
コードをコピー | |||
safe_mode=オン (セーフモードを使用) safe_mode=Off(セーフモードをオフにする) Apacheのhttpd.confにおけるVirtualHostの対応設定方法 php_admin_flag セーフモード オン(セーフモードを使用) php_admin_flagsafe_mode Off(セーフモードをオフにする) または: php_admin_valuesafe_mode1 (セーフモードを使用) php_admin_valuesafe_mode0 (セーフモードをオフにする)
|
名前 | デフォルト値 | 変更可能範囲 | 記録を更新 |
---|---|---|---|
セーフモード | 「0」 | PHP_INI_SYSTEM | |
safe_mode_gid | 「0」 | PHP_INI_SYSTEM | PHP 4.1.0以降で利用可能 |
safe_mode_include_dir | NULL | PHP_INI_SYSTEM | PHP 4.1.0以降で利用可能 |
safe_mode_exec_dir | 「」 | PHP_INI_SYSTEM | |
safe_mode_allowed_env_vars | 「PHP_」 | PHP_INI_SYSTEM | |
safe_mode_protected_env_vars | 「LD_LIBRARY_PATH」 | PHP_INI_SYSTEM | |
open_basedir | NULL | PHP_INI_SYSTEM | |
機能を無効にする | 「」 | php.iniのみ | PHP 4.0.1 以降で利用可能 |
クラスを無効にする | 「」 | php.iniのみ | PHP 4.3.2 以降で利用可能 |
セーフモードをオンにすると、以下の機能リストの機能が制限されます:
関数名 | 制限事項 |
---|---|
dbmopen() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
dbase_open() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
ファイルプロ() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
filepro_rowcount() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
filepro_retrieve() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
ifx_* | sql_safe_mode 制限、(!= セーフ モード) |
イングレス_* | sql_safe_mode 制限、(!= セーフ モード) |
mysql_* | sql_safe_mode 制限、(!= セーフ モード) |
pg_loimport() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
posix_mkfifo() | 操作されているディレクトリが、実行されているスクリプトと同じUID(所有者)を持っているかどうかを確認します。 |
ぷてんv() | ini によって設定されたsafe_mode_protected_env_vars オプションとsafe_mode_allowed_env_vars オプションに従います。 putenv() 関数の関連ドキュメントを参照してください。 |
move_uploaded_file() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
chdir() | 操作されているディレクトリが、実行されているスクリプトと同じUID(所有者)を持っているかどうかを確認します。 |
dl() | この機能はセーフモードでは無効になっています。 |
バックティック演算子 | この機能はセーフモードでは無効になっています。 |
shell_exec() (機能的にはバックティック関数と同じ) | この機能はセーフモードでは無効になっています。 |
実行() | 実行操作は、safe_mode_exec_dir で設定されたディレクトリでのみ実行できます。何らかの理由で、現在、実行可能オブジェクトのパスで .. を使用することはできません。この関数のパラメータには escapeshellcmd() が適用されます。 |
システム() | 実行操作は、safe_mode_exec_dir で設定されたディレクトリでのみ実行できます。何らかの理由で、現在、実行可能オブジェクトのパスで .. を使用することはできません。この関数のパラメータには escapeshellcmd() が適用されます。 |
パススルー() | 実行操作は、safe_mode_exec_dir で設定されたディレクトリでのみ実行できます。何らかの理由で、現在、実行可能オブジェクトのパスで .. を使用することはできません。この関数のパラメータには escapeshellcmd() が適用されます。 |
ポペン() | 実行操作は、safe_mode_exec_dir で設定されたディレクトリでのみ実行できます。何らかの理由で、現在、実行可能オブジェクトのパスで .. を使用することはできません。この関数のパラメータには escapeshellcmd() が適用されます。 |
fopen() | 操作されているディレクトリが、実行されているスクリプトと同じUID(所有者)を持っているかどうかを確認します。 |
mkdir() | 操作されているディレクトリが、実行されているスクリプトと同じUID(所有者)を持っているかどうかを確認します。 |
rmdir() | 操作されているディレクトリが、実行されているスクリプトと同じUID(所有者)を持っているかどうかを確認します。 |
名前を変更() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 |
リンク解除() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 |
コピー() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 (<font face="NSimsun">source</font> and <font face="NSimsun">target</font> に) |
chgrp() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
ちょん() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 |
chmod() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 また、SUID、SGID、スティッキービットは設定できません |
タッチ() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 |
シンボリックリンク() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 (注: テスト対象のみ) |
リンク() | 操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。(注: テスト対象のみ) |
apache_request_headers() | セーフ モードでは、「authorization」で始まるヘッダー (大文字と小文字が区別されます) は返されません。 |
ヘッダー() | セーフ モードでは、WWW-Authenticate が設定されている場合、現在のスクリプトの uid がこのヘッダーの realm 部分に追加されます。 |
PHP_AUTH変数 | セーフ モードでは、変数 <code class="varname"><font face="NSimsun">PHP_AUTH_USER</font> 、<font face="NSimsun">PHP_AUTH_PW</font> 和 <font face="NSimsun">PHP_AUTH_TYPE</font> 在 <font face="NSimsun">$_SERVER</font> 中不可用。但无论如何,您仍然可以使用 <font face="NSimsun">REMOTE_USER</font> PHP_AUTH_USER
| 、
highlight_file()、show_source() | 🎜操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。 (注: バージョン 4.2.1 以降のみ有効) 🎜 🎜 🎜 🎜🎜parse_ini_file()🎜🎜 🎜操作されているファイルまたはディレクトリが、実行されているスクリプトと同じ UID (所有者) を持っているかどうかを確認します。 操作されているディレクトリが、実行されているスクリプトと同じ UID (所有者) を持つかどうかを確認します。(注: バージョン 4.2.1 以降のみ有効) |
set_time_limit() | セーフモードでは動作しません。 |
最大実行時間 | セーフモードでは動作しません。 |
メール() | セーフ モードでは、5 番目のパラメーターはブロックされます。 (注: PHP 4.2.3 以降のみ影響を受けます) |
同様に、PHP 拡張機能の一部の関数も影響を受けます。 (モジュールのロード: dl 機能はセーフ モードでは禁止されます。拡張機能をロードしたい場合は、php.ini で拡張機能のオプションを変更し、PHP の起動時にロードするだけです)
PHP セーフ モードがオンになっている場合、システム プログラムを実行する必要がある場合は、safe_mode_exec_dir オプションで指定されたディレクトリ内のプログラムである必要があります。そうでない場合、実行は失敗します。実行が許可された場合でも、フィルタリングのために自動的にescapeshellcmd関数に渡されます。
コマンドを実行する次の関数のリストが影響を受けます:
exec、shell_exec、パススルー、システム、ポップ
また、バックタグ演算子(`)もオフになります。
セーフモードで実行した場合、エラーは発生しませんが、putenv関数は無効となります。同様に、PHP 環境変数を変更しようとする他の関数 set_time_limit および set_include_path も無視されます。
セーフモード後の影響:
ファイル所有者のチェックは、関数がファイル システムにアクセスするときに実行されます。デフォルトでは、ファイル所有者のユーザー ID がチェックされ、ファイル所有者のグループ ID (gid) を変更できる場合は、safe_mode_gid オプションで指定されます。
システム上に共有ライブラリ ファイルがある場合、インクルードまたは要求する必要が生じたときに、safe_mode_include_dir オプションを使用してパスを設定し、コードが適切に動作することを確認できます。 (インクルード パス:safe_mode_include_dir オプションを使用してさらに多くのインクルード パスを含める場合は、unix/linux システムではコロンを使用して、Windows では include_path オプションと同様にセミコロンを使用して区切ることができます)
たとえば、セーフ モードで /usr/local/include/php にあるファイルを含める場合は、オプションを次のように設定できます:
safe_mode_include_dir=/usr/local/include/php
インクルードされたファイルを実行する必要がある場合は、safe_mode_exec_dir オプションを設定できます。
たとえば、/usr/local/php-bin パス内のファイルを実行可能にする必要がある場合は、オプションを次のように設定できます:
safe_mode_exec_dir=/usr/local/php-bin
(実行可能ファイル: 実行するプログラムが /usr/bin ディレクトリにある場合、指定したオプションで実行できるパスにこれらのバイナリ ファイルを接続できます)
特定の環境変数を設定したい場合は、safe_mode_allowed_env_vars オプションを使用できます。このオプションの値は、環境変数のプレフィックスです。デフォルトでは、php_ で始まる環境変数が許可されます。これを変更する場合は、このオプションの値をカンマで区切って設定できます。
たとえば、タイムゾーンの環境変数 tz が以下で許可されている場合、このオプションの値を次のように変更します。
safe_mode_allowed_env_vars=php_,tzセーフモードに加えて、PHPはPHPのセキュリティを確保するための他の多くの機能も提供します。
1. [PHPのバージョン番号を隠す]
php.ini で Expose_php オプションを使用すると、Web サーバーによる PHP レポート情報の漏洩を防ぐことができます。以下の通り:
expose_php=on
このセットアップ全体を使用すると、Web サーバーをターゲットとする自動スクリプトによる一部の攻撃を阻止できます。通常、http ヘッダー情報には次の情報が含まれます:
サーバー:apache/1.3.33(unix)php/5.2.4mod_ssl/2.8.16openssl/0.9.7c
expose_phpオプションをオンにすると、上記のヘッダー情報にPHPのバージョン情報が含まれなくなります。
もちろん、ユーザーが Web サイトにアクセスすると、.php ファイル拡張子も表示されます。完全に異なるファイル拡張子を使用したい場合は、httpd.conf で次の行を見つける必要があります:
addtype application/x-httpd.php
.php を任意のファイル拡張子に変更できます。ファイル拡張子はスペースで区切って好きなだけ指定できます。サーバー側で php を使用して .html および .htm ファイルを解析する場合は、次のようにオプションを設定します:
addtype application/x-httpd.html.htm
(HTML の解析: PHP を使用してすべての HTML ファイルを解析するように Web サーバーを構成します。ただし、サーバー側以外のコードでも解析するために PHP が必要な場合は、サーバーのパフォーマンスに影響します。静的ページにはさまざまな拡張子を使用できます。これにより、PHP スクリプト エンジンへの依存を排除してパフォーマンスを向上させることができます)
2. [ファイルシステムのセキュリティ]
セーフ モードでは、スクリプト所有者は自分に属するファイルのみにアクセスできるように制限されますが、open_basedir オプションを使用して、アクセスする必要があるディレクトリを指定できます。ディレクトリを指定すると、PHP はそのディレクトリとそのサブディレクトリを除く他のディレクトリへのアクセスを拒否します。 open_basedir オプションはセーフ モード以外でも機能します。
/tmp ディレクトリのみにアクセスするようにファイル システムを制限する場合、設定オプションは次のとおりです:
open_basedir=/tmp
3. [機能アクセス制御]
カンマ区切りを使用して disable_functions オプションで関数名を設定すると、これらの関数が PHP スクリプトでオフになります。この設定はセーフ モード以外でも機能します。
disable_functions=dl
もちろん、disable_classes オプションを使用して一部のクラスへのアクセスをオフにすることもできます。
4.[データベースセキュリティ]
PHP スクリプトに、フォーム値に基づいて実行される mysql クエリが含まれているとします。
$sql=”update mytable setcol1=”.$_post["value"].”where Col2=’somevalue’”;
$res=mysql_query($sql,$db);
列col1を更新するために、$_post["value"]に整数値を含めたいとします。ただし、悪意のあるユーザーがフォーム フィールドにセミコロンを入力し、その後に任意に実行したい SQL ステートメントを入力する可能性があります。
たとえば、$_post["value"] によって送信された値が以下であると仮定します。
0;admin_users(username,password) の値に挿入 ('me','mypassword');
次に、このクエリが mysql クエリに送信されると、次の SQL になります:
mytableセットcol1=0を更新します;
admin_users(username,password) の値に挿入 ('me','mypassword');
どこでcol2=’somevalue’;
これは明らかに有害なクエリです。まず、このクエリは mytable テーブルのcol1を更新します。これについては何も面倒なことはありませんが、2 番目の式では、ログインできる新しい管理者を挿入する挿入式が実行されます。 3 番目の式は破棄されますが、同時に SQL パーサーは有害なクエリが完了する前にエラーをスローします。この攻撃は、よく SQL インジェクション (注: SQL インジェクション) と呼ばれるものです。
もちろん、SQL インジェクションには問題があります。相手はデータベースの構造を理解している必要があります。この例では、攻撃者は、テーブル admin_users が存在し、そこにユーザー名とパスワードのフィールドが含まれていることを知り、同時に、保存されているパスワードが暗号化されていないことを知っています。
あなた自身を除いて、平均的な Web サイト訪問者はデータベースに関するこの情報を知りません。ただし、ソース コードを開発するオンライン電子商取引プログラムを使用している場合、または無料のディスカッション掲示板プログラムを使用している場合は、これらのデータ テーブルの定義が知られているか、一部のユーザーがデータベースにアクセスできます。
さらに、スクリプト出力ではクエリ エラーが表示されます。これには、データベース構造に関する多くの重要な情報が含まれています。機能している Web サイトでは、display_errors オプションをオフに設定し、display_errors の代わりに log_errors を使用して警告メッセージとエラー メッセージをファイルに挿入することを検討する必要があります。
(データベース権限: これは非常に重要です。スクリプトを介してデータベースに正しく接続するための適切な権限のみが必要です。データベースに接続するためにスクリプト内で管理者を使用しないでください。これを行うと、攻撃者が攻撃します。攻撃者は、他の同一サーバー上の権限を含む、データベースの完全な権限を取得することが可能です)
。SQL インジェクション攻撃を防止したい場合は、ユーザー フォームで送信されたコンテンツが実行可能な SQL 式ではないことを確認する必要があります。
前の例では、整数値を使用して更新しました。一重引用符の後に文字列が続く場合、攻撃者は SQL 式全体のセミコロンの前に閉じ引用符を送信する必要があります。ただし、magic_quotes_gpc オプションが有効になっている場合、Web フォームで送信された引用は自動的にエスケープされます。
悪意のある攻撃者による SQL インジェクション攻撃を防ぐために、送信されたデータが合法であることを常に確認する必要があります。必要な値が整数値の場合は、is_numeric 関数を使用して式の値をテストするか、settype 関数を使用して数値に変換し、愚かな SQL ステートメントをクリアします。
SQL 式で複数の値を送信する必要があるプログラムを開発する場合は、sprintf 関数を使用して、各値のデータ型を示す書式設定文字を使用して SQL 文字列を構築できます。以下の例を見てください:$sql=sprintf(“update mytable setcol1=%d wherecol2=’%s’”, $_post["number"], mysql_escape_string($_post["string"]));
前の例では、mysql データ全体が使用されているため、この文字列は mysql_escape_string 関数によってフィルターされています。他のデータベースの場合は、addslashes 関数を使用してエスケープするか、他の方法を使用できます