PHP complies with the security mechanisms regarding file and directory permissions in most server systems. This allows administrators to control which files are readable within the file system. Special attention must be paid to globally readable files and ensuring that every authorized user's reading of these files is safe.
PHP is designed to access the file system at the user level, so it is entirely possible to write a piece of PHP code to read system files such as /etc/passwd, change network connections, send a large number of print jobs, etc. So you have to make sure that your PHP code is reading and writing the appropriate files.
Please look at the code below. The user wants to delete a file in his home directory. Assume this scenario is that the file system is managed through the web interface, so the Apache user has permission to delete files in the user directory.
Example #1 Failure to perform security checks on variables will lead to...
<?php // 从用户目录中删除指定的文件 $username = $_POST['user_submitted_name']; $userfile = $_POST['user_submitted_filename']; $homedir = "/home/$username"; unlink ("$homedir/$userfile"); echo "The file has been deleted!"; ?>
Since the username and filename variables can be submitted through the user form, you can submit other people's usernames and filenames, and even delete them that should not be deleted. document. In this case, other methods of authentication must be considered. Think about what would happen if the submitted variables were "../etc/" and "passwd". The above code is equivalent to:
Example #2…File system attack
<?php // 删除硬盘中任何 PHP 有访问权限的文件。如果 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!"; ?>
There are two important measures to prevent such problems.
Only gives very limited permissions to PHP web users.
Check all submitted variables.
Here is the improved script:
Example #3 More secure filename checking
<?php // 删除硬盘中 PHP 有权访问的文件 $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); ?>
However, this is still flawed. If the authentication system allows users to create their own login username, and the user chooses to use "../etc/" as the username, the system falls again. Therefore, it is necessary to strengthen the check:
Example #4 More secure file name check
<?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"); } //后略…… ?>
Depending on the operating system, there are various files that need attention, including devices connected to the system (/dev/ or COM1) , configuration files (/ect/ files and .ini files), commonly used storage areas (/home/ or My Documents), etc. For this reason, it is often easier to establish a policy that disables all permissions and only enables those that are explicitly allowed.