PHP 受大多數(shù)服務(wù)器系統(tǒng)中文件和目錄權(quán)限的內(nèi)置安全機制的影響。 這允許控制文件系統(tǒng)中哪些文件是可讀的。應(yīng)該小心對待任何全局可讀的文件, 要確保所有有權(quán)限訪問該文件系統(tǒng)的用戶都可以安全的讀取文件。
PHP 被設(shè)計為以用戶級別訪問文件系統(tǒng), 因此完全可以編寫 PHP 腳本來讀取系統(tǒng)文件,例如 /etc/passwd, 修改網(wǎng)絡(luò)連接,發(fā)送大量打印任務(wù)等。這有一些明顯的影響,因此需要確保讀寫的是合適的文件。
請看下面的腳本,用戶表示想要刪除自己主目錄下的一個文件。 假設(shè) PHP web 界面通常用于文件管理, 因此 Apache 用戶允許刪除用戶主目錄中的文件。
示例 #1 不對變量檢查會導致....
<?php
// 從用戶主目錄移除一個文件
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";
unlink("$homedir/$userfile");
echo "The file has been deleted!";
?>
示例 #2 ... 文件系統(tǒng)攻擊
<?php
// 刪除磁盤中任何 PHP 有訪問權(quán)限的文件。如果 PHP 有 root 權(quán)限:
$username = $_POST['user_submitted_name']; // "../etc"
$userfile = $_POST['user_submitted_filename']; // "passwd"
$homedir = "/home/$username"; // "/home/../etc"
unlink("$homedir/$userfile"); // "/home/../etc/passwd"
echo "The file has been deleted!";
?>
示例 #3 更安全的文件名檢查
<?php
// 刪除磁盤中 PHP 有權(quán)訪問的文件。
$username = $_SERVER['REMOTE_USER']; // 使用認證機制
$userfile = basename($_POST['user_submitted_filename']);
$homedir = "/home/$username";
$filepath = "$homedir/$userfile";
if (file_exists($filepath) && unlink($filepath)) {
$logstring = "Deleted $filepath\n";
} else {
$logstring = "Failed to delete $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");
}
//等等...
?>
根據(jù)操作系統(tǒng)的不同,需要關(guān)心各種各樣的文件,比如設(shè)備條目(/dev/ 或 COM1)、配置文件(/etc/ 文件和 .ini 文件)、 眾所周知的文件存儲區(qū)域(/home/, My Documents)等等。出于這個原因,創(chuàng)建一個禁止所有權(quán)限而只開放明確允許的策略通常更容易些。