Re: Security - chmod 777 - PHP upload/write

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



SED wrote:
> Sometimes when I write a PHP-script and upload it to a ISP through
> password
> protected FTP, the only way to write data to a folder is to run chmod 777
> for that folder, I want to write (or save) a data to (e.g. file-upload,
> flat-file-database). However, if I do so, I have been told, everyone can
> write data to that file, which is a security risk. Is that true?
>
> If I do so, is it right that anyone can write a data to that folder? E.g.
> PHP-script that can reveal everything?

If it's 777, they don't even need to write a PHP script to read/write it.

ANYBODY with a login on the same server, or anybody who manages to break
into that server, will be able to read/write this file.

One common practice is to chown/chmod the files that PHP needs to
read/write so only the PHP user can read/write them.  If the PHP user (see
output of http://php.net/phpinfo) can read/write the files, but nobody
else can, you've raised the bar a little bit to access.

This then limits the access to PHP scripts.

Of course, some other user with a login can write a PHP script, load it in
their browser, and effectively be running as the PHP user and still
read/write your data, same as you.

If you think about this a bit, you'll realize that you've got a chicken
and egg problem:  If *your* PHP script can alter the data, so can theirs. 
If you make it so *their* PHP script can't alter the data, neither can
yours, and your application won't be real useful, eh?

[+} It was rumored at some point that Apache 2 would allow PHP Modules to
be run as different users in different VirtualHosts.  A recent post by
Rasmus makes me think that never happened.  But maybe it did.  RTFM.  If
you *can* set up your server that way, and make each VirtualHost run PHP
Module as a different user, then you can limit access in Apache 2 in a
better way.

You can add a *tiny* bit of a barrier by burying the stuff PHP can
read/write *outside* the web tree, and only display things on your server
using PHP to 'filter' the content.

For example, if you allow JPEGs to be uploaded, set up your PHP
readable/writeable directory in, say, ~/image instead of
~/public_html/images

Then you need a PHP script to 'display' the JPEG:
<?php
  /* display.php */
  if (!isset($_SERVER['PATH_INFO'])){
    trigger_error("Invalid attempt to use display.php without specifying
image filename, possibly for nefarious reasons.", E_USER_ERROR);
    exit;
  }
  $filename = $_SERVER['PATH_INFO'];
  $filename = preg_replace('/[A-Za-z0-9_\\.-]/', '', $filename);
  if ($filename != $_SERVER['PATH_INFO']){
    trigger_error("Invalid character in image filename, possibly for
nefarious reasons.", E_USER_ERROR);
    exit;
  }
  readfile("/full/path/to/your/home/images/$filenaem");
?>

You can even bury it *inside* a directory that the PHP user can *NOT*
read, so the Bad Guy has to "guess" at the name of the directory that they
can read, because it's inside a directory that they can't read:

mkdir access
chmod 600 access
mkdir access/images
chmod 700 access/images
chown apache access/images

So now the 'apache' user (may be 'nobody' or 'www' or ... on your system)
can do what it wants with the images directory, but somebody poking around
in your system won't *KNOW* there is an images directory, cuz they can't
read 'access' directory to find out it's there.

You then change the PHP display.php script to run some basic sanity checks
before presenting any JPEG to the browser.

You can, fairly easily:

Be sure that http://php.net/getimagesize 'works' on the JPEG, so it's
probably a JPEG and not some kind of Trojan/Virus/Whatever.

Only serve up images that were recorded through your application in the
database as having been uploaded.  So if somebody manages to put a JPEG in
your directory, they'd *also* have to hack into your MySQL data to add it
to the database.

Record an http://php.net/md5 hash of the file when it was uploaded, so if
somebody changes the file out from under you, you can do md5() again and
see that it was changed.

If all these security measures are insufficient for your application, then
it's time to buy a dedicated server, where there aren't any other PHP
users other than yourself [*] and then this is all moot.

[*] Of course, on a dedicated server, if a hacker breaks in, they can
probably run PHP and do these "Bad Things" but if they've already broken
in, you've got MUCH BIGGER PROBLEMS than your PHP-alterable data.

For *MOST* web applications, the measures outline here (or similar) are
sufficient, so you can make PHP "secure enough" to manage your risk to an
acceptable level on a shared server.

In some cases, you simply can't, and you need a dedicated server -- But
that's usually something you know you need anyway, for all the *OTHER*
security issues involved in the first place.

PS The ideas above are but a fraction of the kinds of things one can do to
limit access and sanity check content using PHP.

-- 
Like Music?
http://l-i-e.com/artists.htm

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux