Httpd file permission on Apache server - php

I've always used the following codes to create a folder on a Apache server but recently on one of the server I've got permission denied error.
if(!is_dir('img/user/'.$id))
{
mkdir('img/user/'.$id, 0777, true);
chmod('img/user/'.$id, 0777);
}
On internet I found that to upload directory for httpd it needs to have write permissions like this:
drwxrwxrwx 2 user staff 512 Jan 07 12:32 uploads/
Where is this permission set? I do not direct access to the server. Is there any alternatively?

You never want to set permissions to be world writable if you can avoid it, or even readable for that matter. 0770 would be a better option, if still a little broad. The main point is that the folder(s) in question need to be writable by the webserver user. For instance, on many webhosts apache will be run by the user nobody, so a more appropriate permission would look like this:
drwxrwx--- 2 nobody nobody 512 Jan 07 12:32 uploads/
Now, there is a problem if you can't get direct access to set permissions yourself except through PHP, because some web hosts will disallow your ability to run chmod or other permissions or ownership modifications from within PHP. That said, if you're using cPanel (and likely other hosting systems do this as well) you can use the online file manager to accomplish what you want by browsing to the appropriate directory and using change permissions located at the top of the page.
So, ultimately, here's what you need: If you need to be able to create a directory in a particular place, you need to make sure that place is writable by the web server. In your example, that means that you need to set appropriate permissions on img/user first before you attempt to create img/user/$id. That means that img/user either must have permissions of 0770 and must be owned by nobody:nobody (either user or group would work in this context, you don't need both), or it must have permissions of 0777. Then, when you create your specific user directory, you can do it like so:
if(!is_dir('img/user/'.$id))
{
mkdir('img/user/'.$id, 0770, true);
}
... because it will already be owned by the appropriate user and you'll already have write access to it simply because your webserver created it in the first place.
If you can't find a non-PHP way to do it, then you'll have to get your webhost to help.

PHP runs as user: www-data in group: www-data (Ubuntu) or something else depending of the server OS.
You can ask your provider to set the right access on maps / files if you cannot do it yourself by FTP.

Related

Give php permission to create files without permissions error

When using the move_uploaded_file() function in PHP I get the error:
Warning: move_uploaded_file(...): failed to open stream: Permission denied in ...
On my server I have the public_html permissions like:
drwxr-sr-x 7 user www-data 4096 Apr 27 17:48 public_html
Which is recursively through-out the directory.
Have you got any ideas why this might not be working? Or what I can do to help me find out why this is not working.
The system
The server is actually a cluster where the files are on a NAS and the php is on the cluster. I am performing all the permission commands on the device of the NAS as that is where the user FTP's to.
User www-data can not write to public_html directory. Use chmod on your public_html to give www-data write permission:
chmod 775 public_html -R
First off, the SUID and SGID only make sense when used with executable files.
From http://www.codecoffee.com/tipsforlinux/articles/028.html :
SUID (Set User ID) Bit
[...] in case I have an application whose owner is ' root ' and it has its SUID bit set, then when I run this application as a normal user, that application would still run as root. Since the SUID bit tells Linux that the the User ID root is set for this application and whenever this application executes it must execute as if root was executing it (since root owns this file)
SGID (Set Group ID) bit
Just like SUID, setting the SGID bit for a file sets your group ID to the file's group while the file is executing. IT is really useful in case you have a real multi-user setup where users access each others files. As a single homeuser I haven't really found a lot of use for SGID. But the basic concept is the same as the SUID, the files whose SGID bit are set would be used as if they belong to that group rather than to that user alone.
So if none of your web files need to be executed as a normal process, it is best to leave the SGID alone.
Finally if you didn't change your web server's security context, it (most probably, as you didn't mention any paths) tries to move a file which is located in a directory www-data can only read. To move a file you need write access to the directories where the file is and will be moved to. So www-data should be given write access to
the directory where the file lands in the first place (by default: /tmp, in which case nothing's to be done)
the destination directory, where it is intended to be moved to.

I need to enable users of my site to upload images - can i do it without setting the folder permissions to 777

So, basically the question is in the title and a little more detailed scenario:
I have a site's backend written in PHP (on linux server - centos 6) and I actually have only 2 users who have the access to it. They need to be able to upload images via some form. So, I made the simple upload script, but no matter what (or am to ignorant to know :/), the upload only works on folder permissions set to 777, so my question is is this ok, or should I implement some better 'common practice' in this situation?
You don't need the directory permissions at 777. What you need is to be certain the the directory is writable by the web server user, which either means making it owned by the web server user or owned by another user with its group set to the web server user and group-writable permissions.
So if your web server user was www-data for example (other common possibilities include apache, httpd, www):
# Set ownership to the web server user
chown www-data uploads_dir
# and make it writable by the web server user
# could also be 755 (readable by others)
chmod 700 uploads_dir
Or if it must stay owned by your account user (on a shared host for example), set the group to the web server user:
chown youruser:www-data uploads_dir
# and make it group-writable:
chmod 775 uploads_dir
The bottom line is that it is usually not a good idea to assign 777 (world-writable) permissions to a directory. Also, uploads_dir should ideally be placed outside the web server's document root so it isn't available vit HTTP requests.
You can also use something like suphp to run the php scripts as a user, while retaining the ability to have the folder not writeable by any other user or group.
You would need administrative access to your webserver for this, though.
A solution is to use FastCgi.
This make new files and directories owned by the the same user and group.
There is a performance penalty to FastCgi but you get some added security as it restricts php. If you are hosting multiple website with multiple users this could be a good idea.

File permissions; Should my www-folder content be owned by www-data?

This might be a noob question, but can't find an answer anywhere.
I have a problem, which Another file permissions problem have helped me to ALMOST solve.
I have created a user in linux (danny) which has sudo access.
I have also created a new group which name ALSO is danny, and added the user danny to that group. This group has sudo (root) access.
I have all files and folders in my www folder owned by danny/danny group.
I have an image-upload code which is php. This code cannot upload images to a folder called "images" folder which is under the www folder, UNLESS I give the images folder 777 permissions.
So, I have followed the answer on the linked question, and have figured out that the user which the upload-script is run as is "www-data".
According to the answer on the link to the other question I posted, I need to add www-data to a group... But I am stuck here...
Which group should I add to? What should I do from here?
Any tips are appreciated.
Btw, here is some info about www-data and danny
id www-data:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
id danny
uid=1000(danny) gid=33(www-data) groups=33(www-data)
Thanks and if you need more input, just let me know...
In general, NO, your content should not be owned by www-data. The only content which should be owned by www-data are the specific files that you need web applications to be able to modify and specific directories that they need to be able to create or delete files in. The rest should not be owned (or writable) by www-data because every file that www-data can write to is a file that an attacker who compromises your web server (including any scripts or web apps that it is running) will be able to replace with whatever malicious data he may choose.
It is especially important that www-data not own or be able to write to any executable file (e.g., scripts, flash files, documents in Word or other formats with macro capabilities, etc.) because replacing them with malicious executables would provide an easy way to attack users' computers or the web server itself.
I think it makes sense that files being used by www-data is owned by www-data. I mean who else should own it? The most important part is that the web app shouldn't have write access to its own web root. The reason why is becuase a directory traversal vulnerability in a PHP function like copy() or file_put_contents() might allow an attacker to drop a .php backdoor in your web root.
Another important attack to be aware of is that another process or user on the system might want to read or write to your web root, so its important that the very last number be a zero. The middle number is the group and your not using this, so it should be zero as well. The following 2 commands makes your web root readable and executable by apache, and only apache. Sometimes a different user account is used, so run a <?php system('whoami')?> to find out the correct user account.
chown www-data -R /path/to/webroot
chmod 500 -R /path/to/webroot
By the time the attacker has remote code execution to change the privileges of the web root its game over. The whole point is trying to foil the exploit from succeeding.
I'd add www-data user to group danny.
usermod -a -G danny www-data
This way www-data could enter danny's place, but not the opposite.
In order to allow www-data user to write to a danny group folder permission mask has to be like (where wildcard means any value is ok):
d???rwx???
Actually, your problem is that you need the user www-data to have write-access to the images folder.
And you probably want user danny to have full access to the folder as well.
EDIT: Additional word of warning:
having files writeable by your webserver is always a security risk. Be sure to check the files that are written, and make sure people can't upload or change code.
Summary:
* Don't let your webserver run scripts that are writeable, or in a writeable folder.
So make sure only the images/ folder is writeable, and doublecheck that everything that is written, is actually an image!
Either:
Set www-data as owner of the folder,
and chmod u+rwx www.
Set www-data
as part of a group X, and change the
owner of the folder to X, and chmod
g+rwx www.
Set the folder
world-writeable on your server (in
some cases, an acceptable solution
too, but less secure).

PHP and Permissions

I recently moved my website to a new host and now am experiencing some broken code..
I have an uploading script that is now returning this:
move_uploaded_file() failed to open
stream: Permission denied in *..
I've set the upload directory to 777 which worked fine, but my script is needed to have top level permissions..
(As the script itself sets permission to directories, does lots of copying etc)
Is there a way in apache I can set the PHP script to the owner of all the folders on my server?
Thanks
Also
When looking in phpInfo()
Under
apache2handler
User/Group nobody(99)/99
Is this related?
I wouldn't go that route, just give it permissions to the defined upload_tmp_dir, or define upload_tmp_dir to be a directory you have access to. If it is that directory you have problems with. If the target is the problem, and you've 777'ed it, something fishy is going on.
Do you have ssh access to your new host? The reason I ask is that it's probably not best to use the username/group as nobody, as most other services would use this too. I would change it to something like apache
You can then update httpd.conf, adding in these two lines (reloading the config after):
User apache
Group apache
Then, run chown apache:apache -R dir_name to make apache own it.
well,
When you are trying to set the permission like "0777", you must be running on same authority.
What I mean is.
For example, your script tells to change a folder/file permission to 0777, but the folder or file already has a permission and that is '0755' so you are not authorised to make that change. as the user have only 5 authority.
Either, you need to login to FTP and change the folder permission to 0777 and then you have full control over it or you have to stick with using 0755 or similar.

Nobody owner (99 99) in FTP caused by php functions?

I have a script (Joomla) that creates files and directories on the server. The problem is that it creates them under owner 99 99 (nobody) and after I can't delete or modify them by FTP without the help of the server admin.
I think that is move_uploaded_file function of php.
Is there any solution of this problem by the WHM or by the server admin? Can I modify the default owner in ftp?
What happens is the HTTP server is ran by a user called "nobody", and your FTP user is another one. When the upload occurs, the HTTP server creates the file under its username, and your FTP user has no permission to write (or delete) these files.
The easiest way to fix this (but not really secure) is to add both users in a same group, and change the file permissions to allow users of the same group to read/write on these files.
Your admin should take care of it, but you'll have to call chmod() to change the permissions of your uploaded files.
Explaining it better:
The linux/unix file permissions are composed by permissions of user (u), group (g) and others (o).
I'll only cover 3 types of file permisions here, which are read (r), write (w) and execute (x). So, you end up having something like this:
-rw-rw---x 1 jweyrich staff 12288 Oct 24 00:22 avatar.png
The first rw- is the permission (read/write) of the USER that owns the file (jweyrich).
The second rw- is the permission (read/write) of the GROUP that owns the file (staff).
The --x at the end are the permissions (execute) of the OTHERS users..
Your PHP scripts run as "nobody" user (and by, let's say, "nobody" group), so every file you create from your PHP will be owned by the "nobody" user (and his group). A user can be part of one or more groups.
To solve the permission problem, your FTP user and the "nobody" must be in a common group, let's say the admin put your user in the "nobody".
Once they're in the same group, your PHP script has to give "rw" (read/write) permissions to the "nobody" group members. To do so:
chmod("path_to_your_file", 0770);
The 0770 is equivalent to "u+rwx,g+rwx,o-rwx" , which I explain here:
u+rwx = for user (owner, which is "nobody"), give read/write/execute permissions
u+rwx = for group (which is also "nobody"), give read/write/execute permissions
o-rxw = for others, remove the read/write/execute permissions
After that, your FTP user, which is now part of the "nobody" group, will have read//write access to the uploaded files, and thus can also delete the files. It would look like this:
-rwxrwx--- 1 nobody nobody 12288 Oct 24 00:22 avatar.png
It's not the ideal introduction to unix file permissions, but I hope this helps.
The user that PHP runs under - nobody - is set by the system administrator. There's nothing you can do about that.
You can try chown() to change the file's owner if you know the FTP user's ID. Usually though, you will not be allowed to do this from within PHP.
Depending on the group situation on the server, it could be that if you use chmod to change the file's access rights after the file has been uploaded, the FTP account can access the file:
Try this first:
chmod($uploaded_file, 0660); // owner+group read+write
If that doesn't work, try this:
chmod($uploaded_file, 0666); // global read+write
one of these should make the file usable by the FTP account.
The 0666 is highly discouraged because other users on the server could write into your files, but in some configurations, it's the only way to get going.

Categories