Deleting File From Folder permissions 755

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
merrydown
Forum Newbie
Posts: 5
Joined: Sun Jul 10, 2011 4:36 pm

Deleting File From Folder permissions 755

Post by merrydown »

Hi, I am keen to improve my coding practices to make my server a little more secure. I run a dedicated plesk server (centOs) with many domains on it. By default my server (running under fast cgi) makes folders with permissions 755. Each domain has separate FTP username and password. My sites all use php to upload files, process data and write out / overwrite and delete files (images, sitemaps etc).

I have found that unless I give the folders permissions of 777 (as specified for example in the image upload and process script I have adopted and customised) deleting or overwriting files does not work. I am guessing that it is an ownership issue rather than permissions really and am keen to stop using folders with full permissions despite the code I need to run. I have read that 755 should be fine if the same user/owner is accessing the files but am finding a clear answer as to how I can get around this issue and have all my sites working the same on a server where 755 is the highest permission given.

I'd appreciate any help or actual examples as to what I might change in my coding practice so that I can overwrite a file in php that had previously been created by php or ftp each time.

Many thanks (and apologies if this has been covered clearly 999,999 times and I have missed the point)

Jim
cpetercarter
Forum Contributor
Posts: 474
Joined: Sat Jul 25, 2009 2:00 am

Re: Deleting File From Folder permissions 755

Post by cpetercarter »

I assume that your server is set up so that the file owner is the person who first created the file in question. So, for example, if 'john' uploads files using ftp, 'john' would be the owner of these files. The php programme (or, more strictly, the Apache web server) is not 'john'; it has its own user name, often 'www-data'. PHP can accesses files owned by 'john' using the permissions granted to 'everyone else'. So, for php to write to a folder owned by 'john', the permissions need to be 0777.

If you are not happy with folders with 0777 permissions, I can think of two possible solutions.

First, when you first set up a new site, you could run a script which causes php to create the folders into which it will later write files, images etc. The owner of these folders would be 'www-data' (or whatever) and the php programme could then write things into the folder with 0755 permissions. To do this you will need temporarily to give the parent folder 0777 permissions, and revert to 0755 after the necessary 'write' folders have been created. For example, if your programme needs a writable folder 'mysite/uploads', you need to use your ftp programme to give the 'mysite' folder 0777 permissions, then get php to create the 'uploads' folder, then revert the permissions on 'mysite' back to 0755. Note if 'www-data' owns a folder with 0755 permissions, user 'john' (ie the ftp programme) will not be able to write to the folder. Also, if you ever need to remove the site and its files, you will first need to get php to change the permissions on the 'upload' folder to 0777 - your ftp programme will not otherwise be able to remove the folder.

The second possible approach is to use the php ftp extension, if it is available on your server. Quite simply, you store your ftp username and password somewhere secure on the server (eg in encrypted form in a database with the encryption key in a config file outside the document root). You can then use the php ftp functions to open an ftp connection, change the permissions on the folder you want to write to to 0777, write the material to the folder, then change the permissions back again and close the ftp connection. The complication which you may have to think through is how to deal with a situation where two users are trying to write to the same folder at the same time ( a 'race condition'!).

i have used both of these approaches in a podcasting cms - the first for cache folders where php constantly needs to write material; and the second for folders where the 'write' operations are only occasional (eg when the site owner uploads a new audio file).
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Deleting File From Folder permissions 755

Post by Weirdan »

cpetercarter wrote:The php programme (or, more strictly, the Apache web server) is not 'john'; it has its own user name, often 'www-data'.
You missed the fact that OP told he's running PHP via FastCGI. One of advantages of this setup is the ability to run PHP processes under a user account different from the account the webserver is running under. So the rest of your comment isn't really applicable to the problem at hand (or, rather, not the best solution possible).

merrydown, please post the output of

Code: Select all

echo `whoami`; echo `ls -ld $dirname`;
(when accessing the script via webserver).
merrydown
Forum Newbie
Posts: 5
Joined: Sun Jul 10, 2011 4:36 pm

Re: Deleting File From Folder permissions 755

Post by merrydown »

Thanks both for your input so far. I am still working on the issue.
cpetercarter
Forum Contributor
Posts: 474
Joined: Sat Jul 25, 2009 2:00 am

Re: Deleting File From Folder permissions 755

Post by cpetercarter »

You missed the fact that OP told he's running PHP via FastCGI.
Well, that was my first thought too. But if php was running with the user-name of the ftp account, why does he find that he needs 0777 permissions for php to write to a folder?
merrydown
Forum Newbie
Posts: 5
Joined: Sun Jul 10, 2011 4:36 pm

Re: Deleting File From Folder permissions 755

Post by merrydown »

I know that the FTP User for each account is the owner for all FTP'd files as you'd expect and the group is psacIn . Files written by php have the user and group 'Apache'.

I doubt that helps much, but its the only extra info I can offer unless you need something specific to work on?

Cheers again,

Jim
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Deleting File From Folder permissions 755

Post by Weirdan »

merrydown wrote: I doubt that helps much, but its the only extra info I can offer unless you need something specific to work on?
Weirdan wrote: merrydown, please post the output of

Code: Select all

echo `whoami`; echo `ls -ld $dirname`;
(when accessing the script via webserver).
merrydown
Forum Newbie
Posts: 5
Joined: Sun Jul 10, 2011 4:36 pm

Re: Deleting File From Folder permissions 755

Post by merrydown »

I tweaked the script to:
echo exec('whoami');

which returns my ftpUsername (identically to the ls result below)...

I can't get the ls command to work in script (I don't think it likes how I am describing the path? who knows, I tried all the versions I could think of... So I did that part via remote command line:

drwxrwxrwx 2 ftpUsername psacln 4096 Jul 11 22:14

I hope that helps... It seems that php is running under the same user as ftp which makes me confused as to why 755 isn't working, but then I am very novice in these matters really.

Thanks,

Jim
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Deleting File From Folder permissions 755

Post by Weirdan »

For more detailed diagnostics configure and run the following script at least twice, noting the output (example output from my system is at the bottom):

Code: Select all

<?php
// configure this
$dir = 'path/to/dir';
$file = 'filename.ext';

error_reporting(-1);
ini_set('display_errors', true);
clearstatcache();

function s($file) {
    $keys = array(
        'dev', 'ino', 'mode', 'nlink', 'uid',
        'gid', 'rdev', 'size', 'atime',
        'mtime', 'ctime', 'blksize', 'blocks',
    );

    $s = stat($file);
    $ret = array();
    foreach ($keys as $k) {
        $ret[$k] = ('mode' == $k) ? sprintf("%o", $s[$k]) : $s[$k];
    }
    return $ret;
}

echo '<pre>';
echo "EUID: " . exec('id -u') . PHP_EOL;
file_exists($dir) or die("Directory '$dir' does not exist" . PHP_EOL);
echo "Directory stat: " . var_export(s($dir), true) . PHP_EOL;
is_dir($dir)      or die("Directory '$dir' is actually not a directory" . PHP_EOL);
is_writable($dir) or die("Directory '$dir' is not writable" . PHP_EOL);
$fname = $dir . '/' . $file;
if (file_exists($fname)) {
  echo "File '$fname' already exists" . PHP_EOL;
  echo "File stat: " . var_export(s($fname), true) . PHP_EOL;
  echo "Attempting to delete: " . var_export(unlink($fname), true) . PHP_EOL;
} else {
  echo "File '$fname' does not exist, attempting to create: " . var_export(file_put_contents($fname, "dummy") > 0, true) . PHP_EOL;
  file_exists($fname) or die("Failed to create '$fname'" . PHP_EOL);
  echo "Created, file stat: " . var_export(s($fname), true) . PHP_EOL;
}

/*
EUID: 1000
Directory stat: array (
  'dev' => 2065,
  'ino' => 644683,
  'mode' => '40755',
  'nlink' => 2,
  'uid' => 1000,
  'gid' => 1000,
  'rdev' => 0,
  'size' => 4096,
  'atime' => 1310432842,
  'mtime' => 1310434156,
  'ctime' => 1310434156,
  'blksize' => 4096,
  'blocks' => 8,
)
File 'path/to/dir/filename.ext' does not exist, attempting to create: true
Created, file stat: array (
  'dev' => 2065,
  'ino' => 644684,
  'mode' => '100644',
  'nlink' => 1,
  'uid' => 1000,
  'gid' => 1000,
  'rdev' => 0,
  'size' => 5,
  'atime' => 1310434170,
  'mtime' => 1310434170,
  'ctime' => 1310434170,
  'blksize' => 4096,
  'blocks' => 8,
)
*/
merrydown
Forum Newbie
Posts: 5
Joined: Sun Jul 10, 2011 4:36 pm

Re: Deleting File From Folder permissions 755

Post by merrydown »

Hi, thanks for your help, here are the results of that test on my folder as set to 777 as normal. I have run a second test while the folder was set to 755 below that.

Code: Select all

777
----

EUID: 10001
Directory stat: array (
  'dev' => 2051,
  'ino' => 8454969,
  'mode' => '40777',
  'nlink' => 2,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 4096,
  'atime' => 1310439844,
  'mtime' => 1310458738,
  'ctime' => 1310458738,
  'blksize' => -1,
  'blocks' => -1,
)
File 'folderTest/temp/filename.ext' does not exist, attempting to create: true
Created, file stat: array (
  'dev' => 2051,
  'ino' => 8454970,
  'mode' => '100644',
  'nlink' => 1,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 5,
  'atime' => 1310458758,
  'mtime' => 1310458758,
  'ctime' => 1310458758,
  'blksize' => -1,
  'blocks' => -1,
)


----------------------------------------------------------------------

EUID: 10001
Directory stat: array (
  'dev' => 2051,
  'ino' => 8454969,
  'mode' => '40777',
  'nlink' => 2,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 4096,
  'atime' => 1310439844,
  'mtime' => 1310458758,
  'ctime' => 1310458758,
  'blksize' => -1,
  'blocks' => -1,
)
File 'folderTest/temp/filename.ext' already exists
File stat: array (
  'dev' => 2051,
  'ino' => 8454970,
  'mode' => '100644',
  'nlink' => 1,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 5,
  'atime' => 1310458758,
  'mtime' => 1310458758,
  'ctime' => 1310458758,
  'blksize' => -1,
  'blocks' => -1,
)
Attempting to delete: true
----------------------------------------------------------------

755
----

EUID: 10001
Directory stat: array (
  'dev' => 2051,
  'ino' => 8454969,
  'mode' => '40755',
  'nlink' => 2,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 4096,
  'atime' => 1310459379,
  'mtime' => 1310459345,
  'ctime' => 1310459345,
  'blksize' => -1,
  'blocks' => -1,
)
File 'folderTest/temp/filename.ext' does not exist, attempting to create: true
Created, file stat: array (
  'dev' => 2051,
  'ino' => 8454970,
  'mode' => '100644',
  'nlink' => 1,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 5,
  'atime' => 1310459381,
  'mtime' => 1310459381,
  'ctime' => 1310459381,
  'blksize' => -1,
  'blocks' => -1,
)

-------------------------------------------------

EUID: 10001
Directory stat: array (
  'dev' => 2051,
  'ino' => 8454969,
  'mode' => '40755',
  'nlink' => 2,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 4096,
  'atime' => 1310459379,
  'mtime' => 1310459381,
  'ctime' => 1310459381,
  'blksize' => -1,
  'blocks' => -1,
)
File 'folderTest/temp/filename.ext' already exists
File stat: array (
  'dev' => 2051,
  'ino' => 8454970,
  'mode' => '100644',
  'nlink' => 1,
  'uid' => 10001,
  'gid' => 2523,
  'rdev' => -1,
  'size' => 5,
  'atime' => 1310459381,
  'mtime' => 1310459381,
  'ctime' => 1310459381,
  'blksize' => -1,
  'blocks' => -1,
)
Attempting to delete: true
If I read those results correctly, then right now you must be thinking that I am an idiot. It seems that in this test the server can delete and overwrite files in the folder with permissions 755, though I have had problems previously on the same setup. Hmm... I don't understand how this can be, but I just tried an FTPd file and PHP written file and both had the same permissions, group and user too so all of this suggests there are more specific times when this occurs.

Thank you very much for showing me the current state of my server file issue. I think the problem must be true for only some of the domains I have on this server as each have their own settings which should be practically identical but obviously are not. When I find a domain for which the above snippet fails I will continue this thread.

Best wishes and thanks again for your patience.

Jim
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Deleting File From Folder permissions 755

Post by Weirdan »

It seems that in this test the server can delete and overwrite files in the folder with permissions 755
Yep, that's what the script shows. At least now you have a script to quickly check ownership/permissions issues that you may use on your other domains.
Post Reply