Page 1 of 1

File permission UNIX/PHP

Posted: Sat Aug 14, 2010 4:00 pm
by Terminux
Hi everyone!

This is not a direct PHP question, but rather a question about permissions of PHP files under UNIX. I've read many posts on forums elaborating techniques with file permissions, but either they actually didn't work, either I really didn't feel it was the right way to do it...

As a basic fact, an Apache server has a run user and a run group (that you can change if you want). Lets call them apache_user and apache_group. Then usually you have your own user account, and your own group ; let's just call them user and group.

First of all, I begin by a silly question, but I never saw that on the web : I think the most natural way to set a regular "foo.php" PHP file would be a 570 octal permission with "apache_user" owner, and "group" group owner. Is that right? Do I miss something important?

Having these kind of permission would allow you to have "secret" files (like .ini configuration files for instance). Let say you have the file "dbconf.ini" with octal permission 640, "user" owner, and "group" group owner. Then, if I understand everything right, "foo.php" file could read this file, because it belongs to the group "group", and "dbconf.ini" has a 4 octal permission (that is, read permission) for this group.

Now if that is correct, either I did something wrong on my computer, or I need your help because I really don't understand file permissions then because I get "Permission denied" errors..

Here is my configuration :
foo.php with "apache_user" owner, "group" group owner, and 570 permission.
dbconf.ini with "user" owner, and "group" group owner with 640 permission.

The simple code I'm using for foo.php

Code: Select all

if ( !$settings = parse_ini_file('dbconf.ini', true) )
    throw new Exception("Unable to read file dbconf.ini. Aborting..");
echo $settings['database']['hello'] . "<br />" . $settings['database']['bonjour'] . "<br />";
Surprisingly, it does work when I set the permissions of dbconf.ini to 644... So there must be an error in my thinking. Any help will be appreciated. Thank you by advance.

J

Re: File permission UNIX/PHP

Posted: Sat Aug 14, 2010 6:14 pm
by Weirdan
Terminux wrote: First of all, I begin by a silly question, but I never saw that on the web : I think the most natural way to set a regular "foo.php" PHP file would be a 570 octal permission with "apache_user" owner, and "group" group owner. Is that right? Do I miss something important?
There are two problems with such setup:
  • owner is allowed to change files permissions. So even though you've 'denied' apache to write to the file, it still theoretically could do this, by changing file's permissions prior to writing. So if another user may run a script under apache's account, he could write to the file you handed out to apache.
  • you can't normally set such permissions when running under ordinary user. Users are not allowed to change file's owner, only root can do this.
Then, if I understand everything right, "foo.php" file could read this file,
Nope, foo doesn't do anything, it's apache that's interpreting foo.php (by means of mod_php).
because it belongs to the group "group", and "dbconf.ini" has a 4 octal permission (that is, read permission) for this group.
But apache (that's actually trying to read the ini) does not belong to the 'group' group and as such is not allowed to read it.

There are ways to run php under account of php script's owner though, either via mod_suphp / mod_suexec + php-cgi or using dedicated pool of workers running under your account via php-fpm.

Re: File permission UNIX/PHP

Posted: Sun Aug 15, 2010 4:27 pm
by Terminux
First of all thank you very much Weirdan your post was very helpful!

For the first remark (570 permission with apache owner and user group), what is recommended then, what is a good setting?
If I do it like : 'user' owner, 'apache_group' group owner, with 750 permission is it ok?

For the second remark, I understand why it doesn't work thanks to you, and there are two solutions I'm thinking about, your opinion would be very valuable to me if you would tell me what you think :

1/ Add the user 'apache_user' to the group 'group'.. But that sounds really dangerous so I'd prefer the second solution..
2/ Create a special group 'agroup', add 'apache_user' to that group, and give the following configuration to the file 'dbconf.ini' : 'user' owner, 'agroup' group owner and 640 octal permission.
Does this seem secure to you? Do you think of another way?

I like to work with .ini files. I know another safe way to save the db parameters is to include a configuration file directly in apache (with httpd.conf), but I could potentially use the ini files for everything, and I don't feel like including everything directly in apache, this seems just wrong..

Thank you again,
J

Re: File permission UNIX/PHP

Posted: Mon Aug 16, 2010 2:57 am
by Weirdan
The answer pretty much depends on what you're trying to secure from.

You need to define your security policy at least. The following questions are what need to have answers for:
  1. Who are allowed to access the server?
  2. Do they have accounts there? If they don't, how they interact with the server?
  3. What they should be able to do?
  4. What they should NOT be able to do?

Re: File permission UNIX/PHP

Posted: Mon Aug 16, 2010 7:44 am
by Terminux
Hello Weirdan, thank you again!

I should have told you more about my application that's true. I'm setting up a website on a dedicated server.
Users of the website of course have no account on the server, but they have accounts in the website.
They should be able to freely navigate the website as I present it to them, and should never ever be able to generate by any action a computation on the server that I was not planned (and written) by me (if there was an Internet God, I wish he could hear me...).

My first concern is that in the possible (but unlikely I hope!) situation where a malicious user would succeed in inserting a PHP script in my database and somehow make it run as any other script, he could never be able to retrieve the database connection parameters with the rights he's granted, nor change the content of any other PHP script that makes the website run, nor write anything new on the hard drive on the server. The possibilities remain of course considerably dangerous, but at least I limit the access to the most valuable data, and I don't make the hard drive explode...

My idea of making the script belong to specific groups was to allow only specific scripts to perform specific actions (like writing in directories or access the database parameters for instance), but it seems impossible isn't it..? Another way is to register any call to critical functions, and deny access to these functions from anywhere else.. But for the parameters, I hope there is a solution here :(

Basically, is there any possibility that a user could run a script through a form input if I use all the functions in PHP that have been created to secure these kind of inputs (htmlentities with ENT_QUOTES, quotemeta, mysql_real_escape, etc.) ?