文件系统安全

PHP 受大多数服务器系统安全机制的控制,这些安全机制通常是基于文件和目录许可基础的。这使得您可以控制文件系统中的哪些文件可以被读取。您需要特别注意所有全局可读的文件,要保证所有访问该文件系统的用户对它们的读取是安全的。

由于 PHP 在设计的时候,允许用户级访问文件系统,因此编写一个 PHP 脚本使得您能够读取诸如 /etc/passwd,更改您的以太网连接,发送繁重的打印机任务等是完全有可能的。这里有一些明显的关联,您需要保证您读取和写入的是正确的文件。

在以下脚本中,一个用户希望该脚本能够删除它们主目录中的一个文件。这仅仅是假设了一种 PHP WEB 接口通常被用作文件管理的情况,因此 Apache 用户被允许删除用户主目录的文件。

例子 16-1. 薄弱的变量检验将导致……

<?php
// remove a file from the user's home directory
$username = $_POST['user_submitted_name'];
$homedir = "/home/$username";
$file_to_delete = "$userfile";
unlink ("$homedir/$userfile");
echo
"$file_to_delete has been deleted!";
?>
由于用户名是可以从用户表单发送的,因此他们可以提交一个用户名和属于其他人的文件,使得这些文件被删除。在该情况下,您会需要使用另外的表单来授权。考虑一下如果被提交的变量是“../etc/”和“passwd”将会发生什么?这个时候其代码可以被理解为:

例子 16-2. 一个文件系统攻击

<?php
// removes a file from anywhere on the hard drive that
// the PHP user has access to. If PHP has root access:
$username = "../etc/";
$homedir = "/home/../etc/";
$file_to_delete = "passwd";
unlink ("/home/../etc/passwd");
echo
"/home/../etc/passwd has been deleted!";
?>
有两种您必须采取的措施来避免这些问题。

以下是经过改进的脚本:

例子 16-3. 更加安全的文件名检验

<?php
// removes a file from the hard drive that
// the PHP user has access to.
$username = $_SERVER['REMOTE_USER']; // using an authentication mechanisim

$homedir = "/home/$username";

$file_to_delete = basename("$userfile"); // strip paths
unlink ($homedir/$file_to_delete);

$fp = fopen("/home/logging/filedelete.log","+a"); //log the deletion
$logstring = "$username $homedir $file_to_delete";
fputs ($fp, $logstring);
fclose($fp);

echo
"$file_to_delete has been deleted!";
?>
尽管如此,该脚本还是有一些问题。如果您的授权系统允许用户建立他们自己的用户登录,而某用户选择登录“../etc/”,系统将被再次暴露。基于这一点,您可能更愿意编写一个更好的检验:

例子 16-4. 更安全的文件名检验

<?php
$username
= $_SERVER['REMOTE_USER']; // using an authentication mechanisim
$homedir = "/home/$username";

if (!
ereg('^[^./][^/]*$', $userfile))
     die(
'bad filename'); //die, do not process

if (!ereg('^[^./][^/]*$', $username))
     die(
'bad username'); //die, do not process
//etc...
?>

根据您的操作系统的不同,您需要考虑许多各种各样的文件,包括设备项目(/dev/ 或 COM1),设置文件(/etc/ 文件和 .ini 文件),通常的文件存储区(/home/,My Documents)等。基于这一点,建立一个策略禁止所有除了您明确的授权的行为可能要更简单一些。