PHP’s Built-In Solutions For Shared Hosting phpma.com
In my last article, I covered the fundamental security problem that exists when you have multiple websites owned by different people on the same box. The challenge is to secure the box not just from outside attack (something you have to do anyway, and which I’ll cover later in this series), but also to make sure that code running on one website can’t steal confidential data like MySQL passwords from any of the other websites.
This isn’t a problem caused by, or unique to, PHP. It has been a problem with websites ever since the original NCSA httpd was released back in the early nineties with the ability to run Perl scripts via the CGI interface. Over fifteen years later, NCSA httpd has given way to Apache and Perl has given way to mod_php, but the problem is still the same.phpma.com
(On Windows, the problem is a little different, because Windows handles process permissions differently. I’ll look at that in a later article).phpma.com
PHP 4 & 5 ship with two features which were designed to tackle this issue - safe_mode, and open_basedir.
Introducing safe_mode
Safe mode is an optional PHP feature aimed at restricting which files any PHP script can access. It works like this:phpma.com
- When your PHP script is executed, PHP makes a note of which user owns your PHP script. On a shared hosting server, this will be your user account - the account you log into to FTP files up to the server.
- Whilst your PHP script is running, if your script wants to access any other files, PHP checks to see who owns those files first. If the file isn’t owned by the same user who owns the running script, PHP refuses to open the file.
Sounds like a great solution to the problem. Your PHP script can open your files - which is what you want - but it cannot open the files of any of the other customers on the box. So how do we switch it on?phpma.com
Configuring safe_mode
To switch on safe_mode, set “safe_mode=1” in your php.ini file, and restart Apache. Then test your website, and make sure it still works.
If you have PEAR (or a.n.other PHP libraries) installed in a central location on your server and listed in the include_dir setting, you should also add this location to safe_mode_include_dir as well. This tells PHP to skip the owning user test when accessing the PEAR libraries.phpma.com
There are also other things you can configure, right down to enabling / disabling specific PHP functions and classes. Full details, as always, are in the excellent PHP Manual. I won’t be going into them in any detail in this article.
The Problems With safe_mode
Alas, if it sounds too good to be true, then all too often it is ![]()
Any moderately-complicated PHP application will create files on the server. The obvious example is uploaded images to a blog, but it’s just as likely to be cache files for RSS feeds or to reduce database overhead, or a friendly web-based installer like the one that comes with Wordpress. When your script creates these files, the files on disk will be owned by Apache, not by your user account. Remember, Apache doesn’t run with your user account’s privileges; it runs as its own user!
With safe_mode enabled, PHP can’t read any of the files created by Apache. To use safe_mode, your PHP script can never ever write brand new files to disk. (It can write out existing files that you own). You’ll have to store all of your data in the database, which isn’t always convenient or the fastest solution.
It’s also (theoretically) possible to get around safe_mode. safe_mode is a PHP feature, not a security policy enforced by the underlying operating system. A PHP extension (one written in C, not in PHP) could ignore safe_mode and just open any files that it chooses (and that Apache can see). The PHP developers audit the official PHP extensions, to make sure none of them can be abused like this, but when it comes to third-party extensions, you’re on your own.phpma.com
Sadly, PHP is just the wrong place architecturally to solve this security problem, and as a result safe_mode will not be part of PHP 6. If you currently rely on safe_mode to secure your servers, it’s time to start looking at other ways to secure your shared hosts. I hope you’ll find my next article or two about alternatives both useful and timely ![]()
Restricting Access With open_basedir
The second PHP feature that helps is open_basedir. Although it’s documented as part of the safe_mode section of the PHP Manual, to all intents and purposes it is a separate feature that can be switched on and off without requiring safe_mode.


