PHP は、ファイルおよびディレクトリ毎に権限を設定する多くのサーバーシ ステム上に組み込まれたセキュリティを提供します。これにより、ファイ ルシステム内のファイルを読み込み可能に制御することが可能になります。 全てのファイルは世界中から読み込み可能であり、このファイルシステム にアクセスした全てのユーザーから読み込まれても安全であることを確認す る必要があります。
PHPは、ファイルシステムにユーザーレベルのアクセスを許可するように設 計されているため、PHPスクリプトから/etc/password のようなシステム ファイルを読み込み可能としたり、イーサネット接続を修正したり、巨大 なプリンタジョブを出力したりすることができます。これから明らかにわ かることですが、読み書きするファイルを適切に設定する必要があります。
各自のホームディレクトリにあるファイルを削除する次のスクリプトを見 てみましょう。これは、ファイル管理用にWebインターフェイスを使用す る場合に通常生じるような設定を仮定しています。この場合、Apacheユー ザはそのユーザーのホームディレクトリにあるファイルを削除可能です。
例1 甘い変数の確認から生じるリスク
<?php
// ユーザーのホームディレクトリからファイルを削除する
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
unlink("$homedir/$userfile");
echo "ファイルは削除されました!";
?>
例2 ... ファイルシステムへの攻撃
<?php
// 外部からPHPユーザーがアクセス可能なハードドライブを削除します。PHPが
// ルートのアクセス権限を有している場合、
$username = $_POST['user_submitted_name']; // "../etc"
$userfile = $_POST['user_submitted_filename']; // "passwd"
$homedir = "/home/$username"; // "/home/../etc"
unlink("$homedir/$userfile"); // "/home/../etc/passwd"
echo "ファイルは削除されました!";
?>
例3 より安全なファイル名の確認
<?php
// PHPユーザーがアクセス可能なハードドライブからファイルを削除する。
$username = $_SERVER['REMOTE_USER']; // 認証機構を使用する
$userfile = basename($_POST['user_submitted_filename']);
$homedir = "/home/$username";
$filepath = "$homedir/$userfile";
if (file_exists($filepath) && unlink($filepath)) {
$logstring = "$filepath を削除しました\n";
} else {
$logstring = "$filepath の削除に失敗しました\n";
}
$fp = fopen("/home/logging/filedelete.log", "a");
fwrite($fp, $logstring);
fclose($fp);
echo htmlentities($logstring, ENT_QUOTES);
?>
例4 より安全なファイル名の確認
<?php
$username = $_SERVER['REMOTE_USER']; // 認証機構を使用する
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
$filepath = "$homedir/$userfile";
if (!ctype_alnum($username) || !preg_match('/^(?:[a-z0-9_-]|\.(?!\.))+$/iD', $userfile)) {
die("Bad username/filename");
}
//etc...
?>
オペレーティングシステムにより、注意するべきファイルは大きく変化し ます。これらには、デバイスエントリ(/dev/ または COM1)、設定ファイ ル(/etc/ ファイルおよび .ini ファイル)、よく知られたファイル保存領 域 (/home/、 My Documents)等が含まれます。このため、明示的に許可す るもの以外の全てを禁止する方針とする方が通常はより簡単です。