[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
module.
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?
Keith
====================
cache at dowebscentral.com
More information about the thelist
mailing list