PHP セキュリティ ガイドhttp://hhacker.com/files/200709/1/index.html
?
PHP は安全です
【原作書籍情報】
《SAMS 10 分でわかる PHP 学習》
著者: クリス・ニューマン
出版社 : Sams Publishing
公開日: 2005 年 3 月 29 日
ISBN: 0-672-32762-7
ページ数 : 264
[翻訳情報]
翻訳者: heiyeluren
翻訳日: 2006-3-15
翻訳された章: 「レッスン 24. PHP セキュリティ」
中国語名: PHP セキュリティ
PHP は間違いなく非常に強力なサーバーサイド スクリプト言語ですが、強力な機能には常に重大な危険が伴います。この章では、PHP の潜在的な危険の一部を防ぐために PHP のセーフ モードを使用する方法を学習します。
【セーフモード】
PHP のセーフ モードは、複数のユーザー アカウントが存在する PHP オープン Web サーバー上に基本的な安全な共有環境を提供します。 PHP が Web サーバー上でセーフ モードで実行されている場合、一部の機能は完全に無効になり、使用可能な機能の一部は制限されます。
[制限を適用するにはセーフモードを使用してください]
セーフ モードでは、ファイル システムにアクセスしようとする一部の機能が制限されます。 Web サーバーのユーザー ID を実行して、特定のファイルを操作するには、そのファイルに対する読み取りまたは書き込みアクセス権が必要です。PHP がこの制限機能を実装することに問題はありません。
セーフ モードがオンの場合、ローカル ファイルの読み取りまたは書き込みを試行すると、PHP は現在アクセスしているユーザーがターゲット ファイルの所有者であるかどうかを確認します。あなたが所有者でない場合、操作は無効になります 終わり。 (書き込み権限: 下位レベルのファイル アクセス権限では、システム オペレーティング システムでのファイルの読み取りまたは書き込みが許可される場合があります。PHP のセーフ モードでは、他のユーザーのファイルを操作できません。 する。もちろん、Web サーバーはグローバル書き込み権限を使用して任意のファイルにアクセスできる場合があります。 )
セーフモードをオンにすると、以下の機能リストの機能が制限されます:
chdir 、move_uploaded_file、 chgrp、parse_ini_file、chown、rmdir、コピー、名前変更、fopen、require、 ハイライトファイル、ショーソース、インクルード、シンボリックリンク、リンク、タッチ、mkdir、 リンクを解除
同様に、PHP 拡張機能の一部の関数も影響を受けます。 (モジュールのロード: セーフモードでは dl 機能が禁止されます。拡張機能をロードしたい場合は、php.ini で拡張機能のオプションを変更し、PHP の起動時にロードするだけです)
PHP セーフ モードがオンになっている場合、オペレーティング システム プログラムを実行する必要がある場合は、safe_mode_exec_dir オプションで指定されたディレクトリ内のプログラムである必要があります。そうでない場合、実行は失敗します。実行が許可された場合でも、フィルタリングのために自動的にescapeshellcmd関数に渡されます。
コマンドを実行するための次の関数リストが影響を受けます:
exec、shell_exec、passthru、system、popen
さらに、バックタグ演算子 (`) もオフになります。
セーフモードで実行した場合、エラーは発生しませんが、putenv関数は無効になります。同様に、PHP 環境変数を変更しようとする set_time_limit や set_include_path などの他の関数も無視されます。
[セーフモードをオンにする]
PHP のセーフ モードをオンまたはオフにするには、php.ini のsafe_mode オプションを使用します。現在 Web サーバーを共有しているすべてのユーザーに対してセーフ モードを有効にしたい場合は、構成オプションを次のように設定するだけです:
セーフモード = オン
関数がファイル システムにアクセスするときに、ファイル所有者がチェックされます。デフォルトでは、ファイル所有者のユーザー ID がチェックされますが、ファイル所有者のグループ ID (GID) を、safe_mode_gid オプションで指定されたものに変更できます。
システム上に共有ライブラリ ファイルがある場合、インクルードまたは要求する必要がある場合は、次のように使用できます。 safe_mode_include_dir オプションを使用してパスを設定し、コードが正しく動作することを確認します。 (パスを含める: を使用したい場合は、 safe_mode_include_dir オプションにはさらに多くのインクルード パスが含まれているため、include_path を好きにすることができます オプションは同じです。Unix/Linux システムではコロンを使用して区切ります。Windows ではセミコロンを使用して区切ります)
たとえば、/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 のセキュリティを確保するための他の多くの機能も提供します。
[ PHP を隠す ]
php.ini で Expose_php オプションを使用すると、Web サーバーによる PHP レポート情報の漏洩を防ぐことができます。以下のように:
expose_php = オン
このセットアップ全体を使用すると、Web サーバーをターゲットとする自動スクリプトによる一部の攻撃を阻止できます。通常、HTTP ヘッダー情報には次の情報が含まれます:
サーバー: Apache/1.3.33 (Unix) PHP/5.0.3 mod_ssl/2.8.16
OpenSSL/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 スクリプト エンジンへの依存を排除し、パフォーマンスを向上させることができます)
[ファイル システム セキュリティ]
セーフ モードでは、スクリプト所有者は自分に属するファイルのみにアクセスできるように制限されますが、open_basedir オプションを使用して、アクセスする必要があるディレクトリを指定できます。ディレクトリを指定すると、PHP はそのディレクトリとそのサブディレクトリ以外のディレクトリへのアクセスを拒否します。 open_basedir オプションはセーフ モード以外でも機能します。
ファイル システムが /tmp ディレクトリのみにアクセスするように制限する場合、設定オプションは次のとおりです:
open_basedir = /tmp
[機能アクセス制御]
カンマ区切りを使用して disable_functions オプションで関数名を設定すると、これらの関数は PHP スクリプトでオフになります。この設定はセーフ モード以外でも機能します。
disable_functions = dl
もちろん、disable_classes オプションを使用して一部のクラスへのアクセスをオフにすることもできます。
[データベースセキュリティ]
PHP スクリプトに、フォーム値に基づいて実行される Mysql クエリが含まれているとします。
$sql = "UPDATE mytable SETcol1 = " . $_POST["value"] "
WHEREcol2 = 'somevalue'";
$res = mysql_query($sql, $db);
列col1を更新するために、$_POST["value"]に整数値を含めたいと考えています。ただし、悪意のあるユーザーはフォーム フィールドにセミコロンを入力し、その後に任意に実行したい SQL ステートメントを入力する可能性があります。
たとえば、$_POST["value"] によって送信された値が次のとおりであるとします。
0; INSERT INTO admin_users (ユーザー名、パスワード)
VALUES ('me', 'mypassword');
次に、このクエリが Mysql クエリに送信されると、次の SQL になります:
UPDATE mytable SETcol1 = 0;
INSERT INTO admin_users (ユーザー名、パスワード)
VALUES ('me', 'mypassword');
WHEREcol2 = 'somevalue';
これは明らかに有害なクエリです。まず、このクエリは mytable テーブルのcol1を更新します。これについては何も面倒なことはありませんが、2 番目の式は実行されます。 入れる ログインできる新しい管理者を挿入する式。 3 番目の式は破棄されますが、同時に SQL パーサーは有害なクエリが完了する前にエラーをスローします。この攻撃は、誰もがよく SQL と呼ぶものです。 インジェクション (注: SQL インジェクション)。
もちろん、SQL インジェクションには問題があります。相手はデータベースの構造を理解している必要があります。この例では、攻撃者は、テーブル admin_users が存在し、そこにユーザー名とパスワードのフィールドが含まれていることを知り、同時に、保存されているパスワードが暗号化されていないことを認識します。
あなた自身を除いて、平均的な Web サイト訪問者はデータベースに関するこの情報を知りません。ただし、ソース コードを開発するオンライン電子商取引プログラムを使用している場合、または無料のディスカッション掲示板プログラムを使用している場合は、これらのデータ テーブルの定義が知られているか、一部のユーザーがデータベースにアクセスできます。
さらに、スクリプト出力ではクエリ エラーが表示されます。クエリ エラーには、データベース構造に関する多くの重要な情報が含まれています。適切に動作する Web サイトでは、設定を検討する必要があります。 display_errors オプションがオフになっており、display_errors の代わりに log_errors が使用されます。 、警告メッセージとエラー メッセージをファイルに挿入します。
(データベースのアクセス許可: これは非常に重要です。正しいアクセス許可がなければ、スクリプトを通じてデータベースに正しく接続できません。データベースに接続するためにスクリプト内で管理者を使用しないでください。 これを実行すると、攻撃者は他の同一サーバー上の権限を含むデータベースの完全な権限を取得できるようになります。攻撃者は GRANT または CREATE USER を実行する可能性があります コマンドを使用して、より多くのアクセス権を取得します。 )
SQL インジェクション攻撃を防止したい場合は、ユーザー フォームで送信されたコンテンツが実行可能な SQL 式ではないことを確認する必要があります。
前の例では、整数値を使用して更新しました。一重引用符の後に文字列が続く場合、攻撃者は SQL 式全体のセミコロンの前に閉じ引用符を送信する必要があります。ただし、magic_quotes_gpc オプションが有効になっている場合、Web フォームで送信された引用は自動的にエスケープされます。
悪意のある攻撃者による SQL インジェクション攻撃を防ぐには、送信されたデータが合法であることを常に確認する必要があります。整数値だけが必要な場合は、次のように使用できます。 is_numeric 関数を使用して式の値をテストするか、settype 関数を使用して式の値を数値に変換し、愚かな SQL ステートメントを排除します。
SQL 式で複数の値を送信する必要があるプログラムを開発する場合は、sprintf 関数を使用して、各値のデータ型を示す書式設定文字を使用して SQL 文字列を構築できます。以下の例を見てください:
$sql = sprintf("UPDATE mytable SET Col1 = %d
WHEREcol2 = '%s'",
$_POST["数値"],
mysql_escape_string($_POST["string"]));
前の例では、Mysql データ全体が使用されているため、この文字列は mysql_escape_string 関数によってフィルタリングされています。他のデータベースの場合は、addslashes 関数を使用してエスケープするか、他のメソッドを使用できます
?
?
注: インターネットからの転載。