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