[thelist] PHP Perl Apache security

Keith cache at dowebscentral.com
Sun Jul 20 00:44:29 CDT 2003

We're wondering how others handle the inherent insecurity of running both 
PHP and Perl in a virtualhosting environment on Linux servers. We've run 
the two solutions below on virtual hosting servers for a few months with no 
problems. But now we are preparing to convert dozens of servers and 
thousands of hosting clients so I want to know if others have found even 
better methods.

Basic scenario:
If PHP is running as Apache module it can write to target files inside the 
domain only if the target file's world bit has write permission (- - 
rw).  If Perl is also running as the same user as Apache, the same is true 
for Perl, the target file's world bit determines permission. Problem: 
Setting a target file's world bit to rw allows any PHP or Perl in another 
domain to also write to the target file.

SuExec scenario:
If suExec is running, Perl runs as the owner of the script and gets it's 
permissions from the target file's owner bit (rw - -). Assuming that the 
script and the target file are owned by the domain user, that allows Perl 
the security of being able to write to the target file while not setting 
the world bit to a level allowing others to write to it. Problem: PHP still 
needs world write permission to write to target files and that allows both 
PHP and Perl in other domains permission to also write to the target file.

open_basedir scenario:
PHP can be jailed in a domain by adding
php_admin_value open_basedir "/root/domain/"
to the domain's virtualhost table. Doing so on all virtualhosts keeps PHP 
from wandering out of the domain it resides in. Problem: that does not 
change the fact that PHP still needs world write permissions on a target 
file within that domain path and setting that permission invites Perl from 
another domain to write to PHP's target file. Even if suExec is running, a 
Perl script in another domain can write to this domain's PHP target file 
because the file has world write permission.

PHP as CGI/suExec scenario:
Instead of running PHP as an Apache module, run it as a CGI. With suExec, 
PHP run as a CGI will inherit the same security that Perl has - PHP can 
write to a file owned by the same user with only rw - - permissions. Since 
world permissions do not need to be set for either PHP or Perl to write to 
the file, 600 permission will work making the file unreadable/unwritable. 
Problem: 1) running PHP as CGI is very inefficient/expensive. 2) running as 
a CGI requires that a PHP shebang (#!/usr/bin/php) be added to all PHP 
files - not a problem if you're just starting out but imagine the hassles 
if you have 15,000 hosting clients on more than 50 servers that will 
suddenly discover their PHP files no longer work.

Solution A: Run suExec and set open_basedir and leave PHP to run as an 
Apache module. For PHP files that do not write to files, leave PHP running 
as an Apache module. For files that do read/write to data files, change the 
extension from .php to .cgi and add the shebang line to the top of the 
file. This actually does work, PHP does run as a CGI and can rw a 0600 file 
owned by the same user. This gets the security of running under suExec when 
needed while otherwise running with the speed and efficiency of an Apache 

Solution B: Run suExec and set open_basedir and leave PHP to run as an 
Apache module. In the Linux user table, add to Apache's group list each of 
the groups of the virtualhost users. This way Apache belongs to it's 
regular group but also belongs to each user's group. Apache no longer gets 
it's instructions from the world bit, it gets them from the group bit, and 
as a member of the group Apache can read and deliver a file with only - r - 
permission. Therefore PHP running as a module of Apache can write to a file 
with - rw - permission - again PHP does not have to set the insecure world 
bit. Since we want Perl and FTP (both running as the owner) in on the 
action, rw rw - is be a perfect permission set for the file. Apache has no 
more privileges on a file than it used to have with 666 permissions, and 
none of the users belong to Apache's group, so we've yet to find a problem 
running Apache against the group bit instead of the world bit.

So, what other methods has anyone else found?

cache at dowebscentral.com

More information about the thelist mailing list