Differentiate each apache user and give permissions - php

In a web application, I want to create a folder for each www-data user and give write permissions just on that folder, and just to that user.
AFTER VALIDATION I can do:
mkdir($file->getPath().mt_rand(0,100000),0700);
This will create a new directory with a random name, in the path $file->getPath() with all permissions to the owner user. But it would give permissions to all www-data users.
If I create a chroot jail I have to copy all files again for each user, because I should create many jails (one for user).
I'm getting crazy with that and don't find out the solution.

If I understand your question right, your problem begins with the structure of the linux permission/user framework. Thus, the Apache process owning user is the one that is creating dirs and files when it is running your script.
If you need user separation for scripts, e.g.: you have different directories for different (virtual) hosts on your server and you don't want the script of one host is acting on data of a different host on the same (apache) server, then you should use 'mpm_itk_module' instead of the more common 'mpm-prefork' apache.
Using this you can go and define the user/group that apache is using when it executes any scripts and e.g. creates directories just by this command for each virtual host entry in the httpd.conf:
<IfModule mpm_itk_module>
AssignUserId USER GROUP
</IfModule>
If you really want to create different directories from ONE script execution, you need the apache process to be owned by root.root and then the script needs to set the permissions and owners for each directoy the way you want.
But it is never a good idea to run even the best scripts on a webserver as root, as you might fail to think of any risk.
The user/right separation by vhosts seems to be a much saver way in my view.
Another point - PHP only - is suPHP -> http://www.suphp.org
EDIT:
Ok, I had a look at your site and even if I can't speak spanish, it looks like you have just one website, acting for different users coming allways thru this webpage. So where is the need for user separation on linux filesystem permissions? You can restrict everything by your application with no need for filesystem users. Even if you give e.g. additional ftp access - restrict it e.g. with proftpd it has its own chroot mech for different users.
You should have to care about filesystem rights only if you can't control who is executing what. Thats a common problem on a multidomain host which you could solve with the mpm_itk_module I mentioned.
Maybe you should describe your situation a little bit more?
EDIT 2:
As suggest in the coment, if you ONLY use apache to give the users access to the files for uploading/manipulation, then just put the files outside(!) the documentroot tree of apache and create simple database to know which file is owned by which user:
user a | file parentdir/filename
This could be an easy table and your php code gives a list to the user from the database which file he is able to see/manipulate and your code does the work as intended by the user action.
As long as you don't give the user access to the files by other services (ftp, ssh, etc.) there is NO need to work with linux user rights at all. Just take care to place the files outside the documentroot of the server so that only your php code has access to the files by the rights of the apache user of your server.
EDIT 3:
Haha, now finally I got your problem after I read a similar post of you: (How can an Apache user write files when having permissions to do it?)
In this case (with REALLY anonymous users on your webpage) you have NO chance to solve this at all. Every visitor is handled as the same one without authentication. And as I assumed in my last EDIT and commented in the similar post: no need to handle with linux file permissions at all.
YOUR SOLUTION ;) :
You need to do the file manipulation in one sessions with session-ids while the user is visiting your page. So your code needs to handle the relation between the visitor (the session-id) and the file he uploaded with this session-id. Using a session-id that is valid as long the visitor is online is the best way to do this. And again - no need for filesystem permissions.... ;)
The second way is with authed users as suggested before: Create a db table with users/passwords to login the webpage (not the server) and another table that holds the user/file relations. Than, after he logs into the webpage, work again with sessions to allow the user accessing/manipulate already uploaded files.

I can that you run apache with mod_php. So then it means that your PHP instance work under apache instance and have apache USER and GROUP. You can create folder and can change owner of this folder but owner must be user in you system (not apache or same virtual user).
But you can store in every directory file for example ".permitions" and put inthat file virtual owner. Next you need filter every write (delete,rename, etc...) attempt to this directory and compare your virtual user and user that stored in .permitions file.
Sample Class (not full but it is more than enough to understand idea):
class UserDirs {
private $path='/home/vusers';
public function mkdir($user){
$d = $this->path.'/'.md5($user);
mkdir($d);
file_put_contents($d."/.owner",$user);
}
public function checkOwner($user, $dirname){
$f = $dirname."/.owner";
$virtual_owner = file_get_contents($f);
return $user === $virtual_owner;
}
}
$d = new UserDirs()
$d->mkdir("foo","bar");
echo $d->checkOwner("foo1","bar") === true ? "OK":"FAIL";
echo $d->checkOwner("foo","bar") === true ? "OK":"FAIL";
You can encapsulate all that you need in this class to work with UserDirs and extend class depending your requirement.

Your users do not have system accounts. It probably is not feasible to create those accounts either. Therefore, I'd recommend managing all of this via the Web UI.
Continue to create your directories as you are. The permissions are fine. Your user interface needs to change though, to only show that user's directory or files. I assume you have a database associated with this page. Associate the usernames and the randomly generated directory name with the user. If someone attempts to go to the direct path and they are NOT the user associated with that directory, kick them back to the login screen.
To illustrate, I created an account named test and was presumably given a unique directory. If I log out, I should not be able to visit that directory because your code would see that
I'm not logged in and therefore don't have access to that directory
If I were to login as test2 and visit the directory of test, your code should see that
I'm not the owner of the directory being visited and should therefore be redirected as appropriate.
You need to add a function that checks the directory the user is visiting and compare it to the directory associated with the user. If they two match, allow them to proceed. If they don't match, redirect the user.

Related

Difference between read & execute, file permission

This may sound like a pretty basic question, but I'm a bit stumped on what constitutes as "reading" a file, and "executing" a file.
For example:
User 1 buys a ticket from an online website, and wants to view the ticket (as a jpeg), which is displayed on the website.
Is this considered to be "reading" the folder? or is this actually executing the folder?
If the user permissions is set to "read only," that means the user CAN access the file via an action on the website(in this case, an image of their purchased ticket), but cannot access the file via direct url link right? Such as, www.exampletickets.com/user1/tickets
Folder Permissions:
Execute -> Actually enter that folder but not be
able to read it's contents, see what files are located there.
Read -> Be Able To Read Folder Contents
Write -> Edit folders data. delete or create new files/folders inside it and etc
File Permissions:
Execute -> if it's script like index.php run it to get data from it
Read -> if it's text file like index.html or index.php be able to read it
Write -> ability to change its data
As for security, this permissions are only an issue when your server is accessible by other (not from your team) users and this was mainly happening when people where using hosting services where they were not getting dedicated operating system but there was one operating system and all the users where uploading their data there. So if not correctly secured, they could view and edit each others source codes.
Today as usual you get dedicated server, with more security tools and operating system which is accessible only by you and no one else (virtualization).
So you don't need to worry that someone will view or change your data as you are the only one who has access to that server.
The webserver (apache, nginx,...) will serve any image files them by reading them, not executing them - same for any other files - regardless if accessed directly or not.
Also, the Linux file permission is given from the machine itself - here, the user will be the user running the webserver instance - usually a linux user named like "www-data". So it does not have anything related to your website's user.
For more information (what are the perfect file and directory permission for your websites ?) -> https://serverfault.com/questions/345833/what-are-perfect-unix-permissions-for-usual-web-project-directories

File system permissions

It was a cms and I would like to set all my files on server to -rw-------
This will make my website working as usual? or they will not read each other, for example i have this:
require_once 'include/checksession.php';
First, you need to understand what each "segment" means.
first triad what the owner can do
second triad what the group members can do
third triad what other users can do
Your permission set (-rw-------) only has permissions on the first triad - the owner of the file - which only has read and write permissions.
read The Read permission refers to a user's capability to read the contents of the file.
write The Write permissions refer to a user's capability to write or modify a file or directory.
execute The Execute permission affects a user's capability to execute a file or view the contents of a directory.
Therefore, the owner of the group can read the contents of the file/directory, write to the file/directory, and modify the file/directory.
Under careful file/directory ownership policies, I guess this will be okay - but I wouldn't count on it. If Apache/Nginx/... doesn't have ownership of the file, your application won't work.
This being said, I'd like to raise a few questions;
Why change the permissions of all files/directories on your server?
Why set a global permission rule, and not individual to each file/directory?
What's the end-goal of this?
I'd take some consideration to Jon T's answer
Depends on whether PHP is running as your user or as as something else (Apache, nobody etc)
If it runs as your user (using suexec or something similar), then nothing else needs to read PHP files.
I'd set these to 0600, giving only your user read/write access. Set to 0400 (read-only) for things like config files.
If you have mutiple FTP users accessing your files, then you need to allow group read/write access as well. Permissions then would be 0660.
If PHP is running as another user and it's not in a chroot'd environment, change your webhost.
Also, on a side note, if your CMS requires permissions anywhere of 0777 (I'm looking at you, Joomla), use a different CMS

PHP change folder owner to apache

So I created a couple of directories and files with FTP, thus the owner is the username I use to login to the server. Now I'd like to allow users of the website to upload images to those directories. Unfortunately for the website to store images, it should be owned by Apache. How can I fix this? I've been reading around on this but can't directly find an answer.
I don't have SSH, so I guess all command-line-things are not applicable for me.
Edit
I tried to then make the folders again using apache, but now ofcourse I can't write any files using ftp into those directories.
Provided that at least the one directory is writeable by the apache user (lets call this directory 'writeabledir', it may be your root dir '/'), you must delete the folders you created via ftp and create a php script to create the directories you need.
If for example you want a directory called users and inside it another directory called upload
Create file makedirs.php on your server.
<?php
$oldumask = umask(0);
mkdir("writeabledir/users/upload",0777,true); // or even 01777 so you get the sticky bit set
umask($oldumask);
?>
Now run your makedirs.php once, by calling your.serv.er/makedirs.php on your browser
EDIT:
If you don't want to delete and recreate your directories,you could always try to change file permissions from ftp.
For exampe with FileZilla, just right click on the desired folder and set permissions to 777. If your ftp user does not have permission to do this, then there is no other way, except from asking an administrator to do this for you.
EDIT2:
Added umask to ensure that folders created by apache are writeable by everyone. (taken from http://us3.php.net/manual/en/function.mkdir.php#1207 )
Friend looks I work in php, some versions change the way of solution, however the most common is already that you want to store it would be necessary to create a database and import it to esu code that also serves to some images you want to come place, plus the wisest thing to do and you create a database with the fields necessary for its realization, import, put in a file directory of your schedule, you also advise using aptana Studio 3 greatly facilitates the creation of codes among many things and low xampp it already comes with apache integrated in one place will help you a lot any questions on installation just look at youtube he will describe

Chmod for PHP web application

Im writing web application. It's have:
index.php
/app - of course, with .htaccess but im not talking about it
/app/session - for sessions, session_save_path(/app/session) must be used on my server
/app/include - index.php includes files from this directory
/app/config - only .xml files, that files reads classes from scripts in include
/images, /styles etc.
My question is:
What is correct chmod settings for above directories? I know what is chmod (im working on Linux) and I know how I can change it, but I can't find useful informations about that. Only articles like "How i can change chmod to 777...
And I don't know who is owner, group and others. My page will be on shared web server, so I think owner is apache, and group is www-data, correct?
Please, tell me what chmod's must have directories (and files? I'm using -R for chmod to files) for safe website. Mainly it comes to the possibility of intrusion by any script.
Wordpress has a nice article explaining unix file permissions. Read it and you'll grasp the basics of it. In short (and not theoratically correct):
Unix systems designate 3 different 'roles': the user, the group and the world. Especially 'the world' seems to confuse people.
Every file AND directory (which are both nodes and as such not that different in Linux systems) is assigned to a user and a group. You can see the user and group as 'owners' of the specific file/directory (I'll talk about 'nodes' further on, because it doesn't really matter). File permissions define who can do what with the nodes. Example given:
The file index.php is assigned to user 'aso' and group 'www-data' and has file permission modus 644. This means that the user (6) has read and write permissions, the group has merely read permissions (4), as is 'the world' (the last 4 of the three digits).
Now first you have to understand that EVERY user on a *nix system is part of a group. The group name is sometimes the same as the user name, but A GROUP IS ANOTHER ENTITY. So it is possible that you have a user as well as a group named 'aso'.
File permssions are build from a 'bitmask' as follows: read permissions are designated by the digit 4, write by 2, and execute by 1. Any combination can be made from this. In example write and execute permissions are designated with 3 (write = 2, execute = 1), and read and execute permissions are designated with 5 (read = 4, execute = 1).
Let's see what this means, and I have to be as fair as to say that I cannot be complete in this matter. Please use Google if you want a complete story.
If I create a file on my *nix system it is automatically assigned to me (my user) and the group my user is part of. Having the permissions 644 this means that I (logged in with my own user) can read the file and can alter (write) it. But I do not have the execute (x) permissions. It doesn't matter however because this only applies to executable scripts (shell scripts, most of the times with a .sh extension). The group the file belongs to ('www-data') only has read permissions, so cannot alter the file. The 'world' also only has read permissions.
Please note that a user can be part of multiple groups, and as such *nix file permissions have a limited scope: you might want to assign write permissions to group 1, and only read permissions to group 2. In traditional file systems this is not possible. However file systems like reiserFS and Ext3 may use an extended ACL to accomplish stuff like that. That's another story however.
What does this all means? It's more easy then expected actually, as long as you understand what the assigned rights mean and what is the difference between a file node and a directory node.
Files
Read: Ability to read it's contents
Write: Ability to alter (write AND delete) it's contents
Execute: Ability to execute the file (execute a script, with all consequences possible)
Directories
Read: Ability to read it's content. Which means: list the node names, but NOT a nodes content, type, etc.
Write: Ability to add/delete files
Execute: Ability to list the it's content, including type, last modification date etc.
Back to your case. If you have a normal setup (a Linux server running Apache and PHP as a module) your files will be assigned to your ftp user and the group 'www-data' (the group Apache is running from). You yourself need read AND write permissions (as sometimes you want to change a file), but DO NOT NEED execute permissions (as PHP - or HTML for that matter - are not executables). So for the user, you'd need a 6 (read = 4, write = 2, combined makes 6). For the group user you only need read permissions, as Apache (or the PHP module) only need to read the contents of your php script. Any other user on the system has nothing to do with your files, and as such need no permissions as all (0).
So, for ALL your scripts, permissions of 640 (read and write for the user, read for the group and none for 'the world') are sufficient.
For the directories your user needs all permissions (read = 4, write = 2, execute = 1, 7 in total). Why? Because it needs to read it's contents (node names), has to be able to determine if it's a file or directory node (and other properties) AND has to be able to add and delete files (you want to add files sometimes, don't you?). So we'll giver your user a 7.
The group however ('www-data', the group Apache is running from) only need read and execute permissions. The read permissions to list the contents (node names) and the execute permissins to list other properties (node type, modification time etc.). It doesn't need write permissions though, because normally you don't want PHP (Apache) to add/delete files from your application tree.
Lastly the 'world', which is every other user on the system (that's NOT the same as the world in it's broadest sense) doesn't need any permissions. Why would anyone else on the server need access to your files?
Combined that would make 750 (all permissions for the user, read and execute for the group, none for others).
Summarized answer to your question, the bare minimum is:
File permissions: 640
Directory permissions: 750
But always good, quite standard and secure enough:
File permissions: 644
Directory permissions: 755
I use 640 on my server. The files are owned by me so I need read and write. Group is www-data so apache can read. PHP scripts don't need execute to run (if using the apache php module which is default. I think you need execute when using cgi), only read. No one else needs access. I have an uploads folder that gives apache write but just that one folder and I typically deny access with .htaccess, disable php to prevent script uploads or put it outside the webroot; depending on the needs of the project.

Am I wrong to make directory executable?

I am writing a file upload using Zend_Form_Element_File(). I created a directory called users in the public directory. When I load the file, I got an error saying page is not found. I check the directory and saw that the permission is drwxr-xr-x. So I change the permission to drwxrw-rw- and load the page again. The page loads properly. But when I upload a file, it produces an error again. So I finally change the permission to drwxrwxrwx and everything runs properly.
My question is that am I doing the usual way that others are doing? I found it strange to make a directory executable.
Can someone explain whether I'm doing it correct? I am just learning Zend framework.
Directories must be executable if a program should be able to "enter" it. Entering a directory basically means accessing any file/directory below that directory.
Having "read" access to a folder allows you to list its contents - what "write" access does is pretty obvious.
However, for security reasons you should check if drwxrwx--- (770) is not sufficient; often your user and the webserver share a common group. If that's the case, there's no need to give any access to "world".
It would be even better to run your scripts as the same user as you - by using fastcgi that wouldn't be too hard, but if you are on shared hosting you usually do not have the necessary access to do this.
Typically when you set permissions on the directory it is so they cascade down to the files within via extended ACLS in the majority of cases. The issue that I see immediately is that you have granted world access which is a bad idea. The only user that needs permissions to the directory (700 at max) is going to be your web server. So I would revert security to be 700 asap.

Categories