start page | rating of books | rating of authors | reviews | copyrights

Programming PHPProgramming PHPSearch this book

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 user can open the file once it's created but before it's locked down. Instead, use the umask( ) function to strip off unnecessary permissions. For example:

umask(077);            // disable ---rwxrwx
$fp = fopen("/tmp/myfile", "w");

By default, the fopen( ) function attempts to create a file with permission 0666 (rw-rw-rw-). Calling umask( ) first disables the group and other bits, leaving only 0600 (rw-------). Now, when fopen( ) is called, the file is created with those permissions.

12.4.2. Session Files

With PHP's built-in session support, session information is stored in files in the /tmp directory. Each file is named /tmp/sess_id, where id is the name of the session and is owned by the web server user ID, usually nobody.

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, variables you store in your sessions are visible to other PHP scripts.

Even worse, other users on the server can create files in /tmp. There's nothing preventing a user from creating a fake session file that has any variables and values he wants in it. The user can then have the browser send your script a cookie containing the name of the faked session, and your script will happily load the variables stored in the fake session file.

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:

To configure safe_mode and the various related settings, you can set the serverwide default in your php.ini file like this:

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 1.2.3.4>
  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>


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.