Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


How does filepermissions work

Posted on 2011-03-12
Medium Priority
Last Modified: 2012-05-11
Im trying to figure out how to limit access to a php-file based on file-permissions, but apparently I dont get it.
I want to limit the possipility to send POST or GET to a php-file from another hostname and figured that it could be done by setting the write-access to Owner only.

But that is not it.

So can anyone explain me how the permissions works.

I expected that domains placed in the same server-directory would be Owner, while others would be Everyone.

I need a real simple explanation on this - preferably with an example of how to limit Writing to a php-file
Question by:petersego
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
LVL 34

Expert Comment

by:Beverley Portlock
ID: 35116172
You don't say what you operation system is, but I'll assume Linux

Permissions come in two parts - membership and access modes. Let us say you create a user profile of 'peter' and also add it to the  group 'users'. Let us say you create a PHP file and set its ownership (via the chown command) to 'peter' and group 'users'.

Now we need to consider the access modes. Basically these are in 3 parts - owner, group, others and they each consist of 3 settings read, write and execute. These are set with the chmod command and they are set in groups of three in the order rwx (read/write/execute) with values 4=read, 2=write, 1=execute, and the groups are in the sequence owner, group, others.

So for your PHP script you might set the modes to 740 with chmod 740 myscript.php. That will give :

Owner: 7 = 4 + 2 + 1 = r w x
Group: 4 = 4 + 0 + 0 = r - -
Others: 0 = 0 + 0 + 0 = - - -

So the owner (peter) can read, write and execute the script, people who are members of the group users can read the script and everyone else is not allowed to do anything with it.

Now on Linux, PHP is usually implemented as an Apache module which means it runs under the group www-data or www or wwwrun (depending on your OS) and similarly for an owner profile. In this example, Apache has no persmission to do anything with the file because it is not 'peter' and it is not a member of 'users'

The problem here is that no matter how you set permissions on different domains within the webroot, apache needs at least read access otherwise it cannot access them. One solution for this is to create a group with the same name as the user ('peter' in our example) and then assign apache membership of that group. This allows apache to read the scipts for a given domain, but it also means that apache can read any other script in any other domain in the web root. You can stop this by using another setting called open_basedir which, for any domain, limits what apache can do.

So, let us take a more concrete example. Two domains example1.org and example2.com which are to be kept independent of each other. So we create two new users and two new groups

user: example1  group: example1
user: example2  group: example2

Then we set the ownership of our scripts

chown -R example1:example1 /var/www/htdocs/example1.org
chmod -R 770 /var/www/htdocs/example1.org

chown -R example2:example2 /var/www/htdocs/example2.org
chmod -R 770 /var/www/htdocs/example2.com

We now add the apache user to the relevant groups (assuming www-data is the apache user)

usermod -a -G example1,example2 www-data

and what we now have are two domains whose code is limited to their user and group and apache. We now need to limit apache to each domain via open_basedir so in each VirtualHost in apache add the following line between the <Directory> and </Directory> tags

in example1.org's Virtualhost
 php_admin_value open_basedir /var/www/htdocs/example1.org

in example2.com's Virtualhost
 php_admin_value open_basedir /var/www/htdocs/example2.com

This limit apache to all files and folders below the path given. There are ways round open_basedir but it is a showstopper for 99.9% of all hacks. Combined with the access methods outlined above you should be fairly secure.


Author Comment

ID: 35116408
Thanks for the comprehensive explanation.
My problem is that Im in no control of the server and I cant imagine that my ISP will change basic settings like this.
I have no access to Apache and I cant change or set CHOWN only CHMOD.
But as I understand you, if I set CHMOD to 740 for the PHP-file, then a domain without me as the user, should not be able to send POST to it.
Ive tried that, but I can still send from another domain that belongs to another username - to the best of my knowledge.
It seems incredible that everyone from anywhere in the world can send to a script through POST.
LVL 34

Expert Comment

by:Beverley Portlock
ID: 35116492
You should be able to limit a script's behaviour, but I'm out of time at the moment. If you have access to the virtualhost then you can still use open_basedir.

I'll pick this up later (much later) if it is still open or tomorrow.
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

LVL 34

Expert Comment

by:Beverley Portlock
ID: 35127208
How are things going? Do you need further explanation?

Author Comment

ID: 35127642
Well, Id be glad if you could clarify if filepermission is set as 740 for the php-file, then another domain, that does not have the same owner should not be able to send POST to it.
That is what I understand from your answer.
Secondly you wrote that I should be able to limit a scripts behaviour. What did you mean by that.
By the way I have no access to the virtualhost.
LVL 34

Accepted Solution

Beverley Portlock earned 2000 total points
ID: 35128150
"By the way I have no access to the virtualhost."

In that case you have a difficulty because we need to be able to set open_basedir and that should be done in the virtual host. I will expand on this point in a moment.

"d be glad if you could clarify if filepermission is set as 740 for the php-file, then another domain, that does not have the same owner should not be able to send POST to it."

As long as each domain has its own owner and group then this isolates one domain from seeing another as the "public" permission in 740 is 0 - ie no permission to read, write or execute. But..... the webserver need to be able to read a script or else PHP cannot load the script to execute it so in my explanation I added the webserver user to each new group. This means that for permissions of 740, the group part (4) grants read permission to any use in that group and that includes the webserver. So although general users of the system or those logging in via FTP cannot move around between domains - the webserver has "read access" to every file or every domain of which it is a group member.

This is where the open_basedir came in. IF each domain has an open_basedir set in its virtualhost then the webserver is limited to staying within that domain. If you access domain1 then the open_basedir stops apache (and thus the user) from accessing domain2 even though the webserver has access to every single file. That is why it is the combination of file/group permissions and open_basedir that secures the machine.

"Secondly you wrote that I should be able to limit a scripts behaviour. What did you mean by that."

You said that it was "...incredible that everyone from anywhere in the world can send to a script through POST". Well, that's the beauty of the internet, but if you want to you can restrict scripts by a few simple checks. For instance putting a "form token" on a form stops many automated scripts (see this http://phpsec.org/projects/guide/2.html for discussion on how to modify a form's behaviour) or you can limit a script that it only functions if the user arrived from another page on your website (by checking $_SERVER['HTTP_REFERER'] ). There are other methods and techniques but these illustrate the general point that forms do not have to blindly accept whatever people tip into them.

Author Closing Comment

ID: 35130459
Thanks. I might not have found the solution, but you certainly have pointed me in several interesting directions.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
These days socially coordinated efforts have turned into a critical requirement for enterprises.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses

604 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question