12.3 File Uploads
File uploads combine the two dangers we've seen so far:
12.4 File Permissions
If only you and people you trust can log into your web server, you don't need to worry about file permissions for files created by your PHP programs. However, most web sites are hosted on ISP's machines, and there's a risk that untrusted people will try to read files that your PHP program creates. There are a number of techniques that you can use to deal with file permissions issues.
12.4.1 Get It Right the First Time
Do not create a file and then change its permissions. This creates a race condition, where a lucky
umask(077); // disable ---rwxrwx $fp = fopen("/tmp/myfile", "w");
By default, the
function attempts to create a file with permission 0666 (
first disables the
12.4.2 Session Files
With PHP's built-in session support, session information is stored in files in the
directory. Each file is named
This means that session files can be read by any PHP script on the server, as all PHP scripts run with the same web server ID. In situations where your PHP code is stored on an ISP's server that is shared with other users' PHP scripts,
One workaround is to ask your service provider to configure their server to place your session files in your own directory. Typically, this means that your VirtualHost block in the Apache httpd.conf file will contain:
php_value session.save_path /some/path
If you have .htaccess capabilities on your server and Apache is configured to let you override Options, you can make the change yourself.
For the most secure session variables possible, create your own session store (e.g., in a database). Details for creating a session store are given in Chapter 7.
12.4.3 Don't Use Files
Because all scripts running on a machine run as the same user, a file that one script creates can be read by another, regardless of which user wrote the script. All a script needs to know to read a file is the name of that file.
There is no way to change this, so the best solution is to not use files. As with session stores, the most secure place to store data is in a database.
A complex workaround is to run a separate Apache daemon for each user. If you add a reverse proxy such as Squid in front of the pool of Apache instances, you may be able to serve 100+ users on a single machine. Few sites do this, however, because the complexity and cost are much greater than those for the typical situation, where one Apache daemon can serve web pages for thousands of users.
12.4.4 Safe Mode
Many ISPs have scripts from several users running on one web server. Since all the users who share such a server run their PHP scripts as the same user, one script can read another's data files. Safe mode is an attempt to address this and other problems caused by shared servers. If you're not sharing your server with other users that you don't trust, you don't need to worry about safe mode at all.
When enabled through the safe_mode directive in your php.ini file, or on a per-directory or per-virtual host basis in your httpd.conf file, the following restrictions are applied to PHP scripts:
and the various
safe_mode = On safe_mode_include_dir = /usr/local/php/include safe_mode_exec_dir = /usr/local/php/bin safe_mode_gid = On safe_mode_allowed_env_vars = PHP_ safe_mode_protected_env_vars = LD_LIBRARY_PATH
Alternately, you can set these from your httpd.conf file using the php_admin_value directive. Remember, these are system-level settings, and they cannot be set in your .htaccess file.
<VirtualHost 184.108.40.206> ServerName domainA.com DocumentRoot /web/sites/domainA php_admin_value safe_mode On php_admin_value safe_mode_include_dir /usr/local/php/include php_admin_value safe_mode_exec_dir /usr/local/php/bin </VirtualHost>