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!"; ?>
|
|
有两种您必须采取的措施来避免这些问题。
对 PHP WEB 用户仅赋予有限的权限。
检验所有提交的变量。
以下是经过改进的脚本:
例子 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)等。基于这一点,建立一个策略禁止所有除了您明确的授权的行为可能要更简单一些。