Example 15-2. ... A filesystem attack
<?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!";
?>
There are two important measures you should take to prevent
these issues.
Only allow limited permissions to the PHP web user binary.
Check all variables which are submitted.
Here is an improved script: Example 15-3. More secure file
name checking
<?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";
fwrite ($fp, $logstring);
fclose($fp);
echo "$file_to_delete has been deleted!";
?>
However, even this is not without it's flaws. If your authentication
system allowed users to create their own user logins, and
a user chose the login "../etc/", the system is
once again exposed. For this reason, you may prefer to write
a more customized check: Example 15-4. More secure file
name checking
<?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...
?>
Depending on your operating system, there are a wide variety
of files which you should be concerned about, including
device entries (/dev/ or COM1), configuration files (/etc/
files and the .ini files), well known file storage areas
(/home/, My Documents), etc. For this reason, it's usually
easier to create a policy where you forbid everything except
for what you explicitly allow.