write to a folder and the security risks - php

I'm using a Thumbnail plugin. It store thumbs in a folder on webroot.
but when it's trying to save the thumb, returns "no writable" error. it directory permission is 755.
If i change permission to 777, error disappears. but I read somewhere 777 permission can cause security issues..
What should I do?

you could change the owner (e.g. chown www-data:www-data your/direcotry/path in linux)
chown [OPTIONS] [Owner][:[Group]] FilenameOrFoldername
that the web-server user (the user who executes php scripts) owns the directory, then he has write access and you can leave the rights to 755.
7 5 5 = rwx r-x r-x
read write execute
first digit = owner
second digit = group
third digit = all other users
means that only the owner has write access (he can add files to the directory in this case the www-data user), the group (www-data) has read and execute rights and the rest has read and execute rights too, so there should not be a security risc with 755.
Here you have a tool where you can calculate the right -> chmod number conversion

the rights is written as owner/group/other, i think you can use 775 rights for your logic.

You could store it somewhere that the web server (like apache or nginx) can't access but your web app server (php, java servlet, whatever) can, and make logic for it to grab it from that folder and serve it up as an image. That way, you ensure that any files uploaded by users aren't ever executed.
It would cost more server resources, so that's something you should consider.
If the files are created by your app and there is no way for the user to directly modify them, then there is no problem with giving it write permissions.

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.

PHP permissions error - I need execute permissions?

I have written a PHP script for file uploading and for testing I gave my upload directory 777 permissions. The script works fine.
Now I want to remove execute permissions for obvious reasons, but once I do that, I get the following error:
move_uploaded_file([filepath]) [function.move-uploaded-file]: failed to open stream: Permission denied
Just taking the permissions down from 777 to 776 causes this error to appear when I try to upload a file. I don't understand why having execute permissions should have anything to do with this - can someone PLEASE shed some light?
Thank you!
A directory must have execute permission to be accessible in Unix & Linux.
Quoting from here:
On a directory, the execute permission (also called the "search bit")
allows you to access files in the directory and enter it, with the cd
command, for example. However, note that although the execute bit lets
you enter the directory, you're not allowed to list its contents,
unless you also have the read permissions to that directory.
I agree with lserni that the fact that revoking execute permission on the directory for O (the third digit) causes the problem is worrisome as it indicates that the webserver is accessing the directory neither as owner nor as member of the group. You should fix that.
Just taking the permissions down from 777 to 776 causes this error to appear
This shouldn't happen. You ought to be able to run with 770 permissions, i.e., the directory should be owned by the Website user ID, with the group of web server.
This way the owner and the webserver are both able to manipulate the directory and the data. Ideally the Web server serving your website ought to assume the same user ID as the website owner, and that way you can keep the directory mode 700 and have it read-writeable and listable only by you.
If the last digit of the permissions is biting you, it means that the server is running with permissions for "everyone", which may be okay for a development site but isn't too good on a shared site (imagine your passwords being readable by any other website owner in the machine).
However, if you're running on a test machine, the 777 permissions are okay. Directory executable bit does not mean executable (a directory can't be executed anyway) but merely 'listable'. Without that bit, you can create and delete files but you can't know whether they're really there, and move_uploaded_files is objecting to this situation.
There are other solutions (e.g. chrooting each virtualhost in Apache); see also What are best practices for permissions on Apache-writable directories?
for removing the execute permissions you need to execute following commands..
chown -R nobody upload_directory
chmod -R 755 upload_directory
The first command changes the owner of your upload_directory and files under it to 'nobody' which is what php operates under. The second changes the upload_directory and files to only allow user access to writing. -R is for Recursive..

Creating, moving, and deleting files in php without setting directory and file permissions to 777?

As the title suggests, I need the ability to create, move, and delete files and folders from php.
If I CHMOD all directories and files to 777, everything works great, but if I do 755 then the scripts die with errors about permissions.
From what I've read, using 777 permissions is insecure and should not be done. I have a VPS, but there are multiple users as I host a number of websites (some of which other people are in control of) and, regardless, I want to do whatever is the "best practice."
So, basically, what I'm wondering is how I should go about this? I'm new to php and "webmastering" and am not sure what to do.
Could anyone point me in the right direction?
One last note: In addition to being able to move and delete files that have been created from php, the scripts also need to move and delete files that have been uploaded via FTP from a Windows machine (I've noticed that by default when I upload files the CHMOD is 755).
EDIT: I it may be relevant for me to mention that I ran phpinfo() and found the following under the section "PHP Credits":
User/Group nobody(99)/99
Permissions are set for what the owner can do, what the owner's user group can do (the owner's peers in the same user group), and what everone else can do. That's what the 3 numbers are for: 753 is a "7" for the owner, a "5" for the group, and a "3" for everyone else. A "7" is full access (read, write, execute). A "5" is read and execute. You need write access to delete.
You should really read up on linux file permissions to see how they work.
I would recommend you use 775 or 770. The last digit is what anyone on the system or any shmoe browsing your site can do, so you want it as low as possible.
As far as your ftp script and your future other-users, just make sure they are in the same group as your apache user. Or, set up a group for those account you want to have access, and add your apache account to it.
In order to be able to manipulate files and directories without 0777 permissions, those files and directories need to be owned by the same user your PHP scripts run as.
You don't need to change things to 777, that gives the owner, group and guest all rights (read, write, execute). You can have it set to 755, or even 700 as long as the owner is whatever whatever the PHP process is running under. Typically this will be the Apache user, since the PHP script is running under the Apache process.
You don't need to give execute privs, but you need to give execute on the directories so that the process can do things like change directories (cd).
Nate, this relates to the basic 101s of UID and GID based access control. I am assuming that your "multiple uses" each have their own UIDs for FTP (and SSH?) access.
Typically files served by the webserver (Apache) must be read-accessible by the Apache child processes which will be running in www-data (or equiv) and hence must be o:r likewise any directories on the path to them must be o:e.
So you broadly have two options: (i) use a suEXEC / suPHP / FastCGI template to initiate PHP scripts in the UID of the owning directory, and (ii) run your scripts under mod_php5 and make any directories where you need script write-access owned by www-data.
This second approach is the most efficient in terms of machine resources, but it is terribly insecure as it in effect gives userA full R/W access to userB's resources and so on.
There's no way to square this circle. If you cannot guarantee shared trust between all users then you must read up on and implement a solution based on the (i) options.
Generally Folders should have 755 and files should have 644 permission set.
I'm facing this problem while working on PrestShop project.
Following PHP script solves my problem.
<?php
exec ("find /path/to/folder -type d -exec chmod 0755 {} +");
exec ("find /path/to/folder -type f -exec chmod 0644 {} +");
?>

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).

Categories