Link to home
Start Free TrialLog in
Avatar of ini_7
ini_7

asked on

Restricting web server's access to files to DocumentRoot with PHP

Greeting brave experts,

This is a tricky question, and I'm looking for some insightful solution ideas.

I'm trying to make my web hosting situation as secure as possible. I'm running apache 2.0.39 with the prefork MPM. This problem would be trivial to solve if I ran the perchild MPM, but I can't for two reasons:
1. It doesn't function at all for me
2. there is some overhead with the perchild MPM that I want to avoid having.

So here's my situation: apache runs as user 'nobody', and thus all files it reads must be readable by 'nobody'. The problem with this is that anyone can use a simple php script to have the same access to files as the web server. Observe:
<?
readfile('/some/file');
?>

My problem with this is that it grants anyone with ftp access to a site on the server the ability to read session information and files that contain database passwords. Not to mention source code for sites that needs to be hidden.

This simply won't do, and if I could tell apache to deny all permission to files above its documentRoot (per virtual server), then my problem would be solved. Even if I could have every virtual server operate in a chroot environment, I could work with that.

If a way to do such a thing is not possible, then I could try running the perchild mpm. The problem there is that apache always crashes if I use that one.

Thank you for your time,
- Travis
Avatar of ini_7
ini_7

ASKER

I found a chroot patch for apache 1.3. This is very close to what I need

http://home.iae.nl/users/devet/apache/chroot/
Travis,

I personally never had done that.  Most of the requirement that your metioned may work (but sounds too technical to me :).

Anyway, have you tried limiting access (deny all) to the top level directory (/), and allow only necessary access for each subdirectories that is/are needed.

Found this page: http://www.tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap29sec254.html
This is really more of a PHP issue than an Apache issue. Your best bet is to run PHP in safe mode (set in php.ini), which prevents any PHP script from reading a file with a different UID than the originating script.

There are several other things you can do with safe_mode, such as safe_mode_exec_dir, disabling certain PHP functions, etc...

Also, you can go further with open_basedir = /home, which wouldn't allow anyone to open a document outside of the users' /home directory (or wherever you create user directories).

IMHO, any responsible ISP with multiple virtualhosts should _always_ run PHP in safe mode. There is simply no compelling reason not to do this. (Yes, I know some users will complain about the limitations, but they can work around them)

See the following resources:

http://cvs.php.net/co.php/php4/php.ini-dist

http://www.php.net/manual/en/printwn/configuration.php#AEN2436
Avatar of ini_7

ASKER

rycamor,

You are absolutely correct! Your answer so far, however, is incomplete. Shortly after I posted this question, I read over everything about PHP's safe mode and decided that this is the exact approach I need to solve my problem. However, I can't enable this globally (we use a lot of restriced access web sites that need the system access) and I've had a really hard time enabling php directives on a per-virtualhost basis in apache2.

Furhtermore, I think the open_basedir directive would be the ideal solution, but only if I could specify each server's documentRoot.

So, my question comes to this:
How can I enable php directives per virtualHost using php4 and apache2?

I've been having stupid problems like this with PHP recently. There have been other weird things. For instance, I have to explicitly turn on register_argc_argv to enable this functionality in the CLI version of PHP, despite the manual saying that this is always enabled in the CLI version.

I know it's annoying question, but thanks for the effort!

ps. My responses will be more timely from now on.
ASKER CERTIFIED SOLUTION
Avatar of rycamor
rycamor
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ini_7

ASKER

Rycamor, your comment is extremely useful! I'll play with this and respond in the next few days.
Avatar of ini_7

ASKER

Good news! I just upgraded my apache and php one minor number up to their most recent versions (2.0.40 and 4.2.3) and it recognizes php directives in my apache config. The relevant parts from an above link are:

php_value [PHP directive name] [value]
php_flag [PHP directive name] [On|Off]
php_admin_value [PHP directive name] [value]
php_admin_flag [PHP directive name] [On|Off]

I'll be using the open_basedir directive to secure my web server.

Additionally, I'm pretty excited to still be able to use Apache2 to do this.

Thanks a lot everyone! I'm accepting rycamor's comment as an answer.
Avatar of ini_7

ASKER

This was an excellent response.