8.5. Safe Mode
PHP's safe_mode directive is intended to address some of the concerns described in this chapter. However, addressing these types of problems at the PHP level is architecturally incorrect, as stated in the PHP manual (http://php.net/features.safe-mode).
When safe mode is enabled, PHP performs an extra check to ensure that a file to be read (or otherwise operated on) has the same owner as the script being executed. While this does cripple many of the examples in this chapter, it does not affect a script written in another programming language. For example, consider the following CGI script written in Bash:
#!/bin/bash echo "Content-Type: text/plain" echo "" cat /home/victim/inc/db.inc
Does the Bash interpreter care that the string safe_mode = On exists within the file php.ini? Does it even check? Of course not. The same applies to Perl, Python, and any other language supported by the host. All of the examples in this chapter can be reproduced easily in other programming languages.
Another significant problem with safe mode is that it does not prevent access to files that are owned by the web server. This is because a script can create another script, and the new script will be owned by the web server and therefore allowed to access files that are also owned by the web server:
<?php $filename = 'file.php'; $script = '<?php header(\'Content-Type: text/plain\'); readfile($_GET[\'file\']); ?>'; file_put_contents($filename, $script); ?>
This script creates the following file:
<?php header('Content-Type: text/plain'); readfile($_GET['file']); ?>
Because the web server creates this file, it is owned by the web server (Apache typically runs as the user nobody):
$ ls file.php -rw-r--r-- 1 nobody nobody 72 May 21 12:34 file.php
This script can therefore bypass many of the safeguards that safe mode provides. Even with safe mode enabled, an attacker is able to view things like session data stored in /tmp because these files are owned by the web server (nobody).
PHP's safe mode does raise the bar, and it can be considered a Defense in Depth mechanism. However, it offers poor protection alone, and it is no substitute for the other safeguards described in this chapter.