I am working on a PHP based website. In the admin there is a section that checks a form field and based on the field looks for a folder on the server. This folder will be in a sub-directory. If it does not exist it needs to be created. After that, previously existing or not, PHP will write file to the folder.
These folders will hold images and PDF files that will be viewed and/or downloaded on the main site.
Here is an example directory structure: merchants/east/user123
In the above merchants and east would definitely exist and user123 may exist or otherwise be created.
Given that info my questions are about folder permissions.
What should folders be set to for the best security.
Should I open them up wider during operations then chmod them (in PHP) after I'm done to something more secure?
What should upper level folders be set to?
770 would be a safe bet for the files. Setting it to that would disallow any public access. I would implement some sort of document delivery system in PHP. PHP will be able to access the non-public files and then send them to the user.
The upper level folders could be set to the same.
Update
As others have said, you can easily chmod them to 600 without any issues. That's the more secure way of handling it (prevents other users on the system from accessing the files). It also omits "execute", which isn't needed for file reading anyway. It's my personal practice to leave the extras in unless there's a defined reason not to.
The upper level folder would need to have read, write and execute permissions for the apache user., the top level folder could be owned by apache, and have permissions like 755 to allow the the webserver to read, write and list files.
You might think about permissions 750 or 700 if you are particularly concerned about other local users or services on the web server from seeing the files in this directory.
For file permissions: 644 or 600 as conventionally they do not need execute permission.
A nice compromise might be to use 750 for directories and 640 for files with owner set to apache, and change the group (chgrp) so that the group for the file allows access to the user that you normally edit the website files with.
I can't think of any significant advantage of the php script increasing and then reducing the permissions.
I think you should consider #chunk's comment about keeping the uploaded files own of the public html directory completely, and serving them back via an file delivery script. Otherwise you would need some careful validation of the content of the files and to tightening up the apache configuration for that particular directory - perhaps using some mimetype checking to make sure that the files really are docs and pdfs.
Related
I am creating a website creation service where users can upload files in an FTP browser interface. I also want them to be able to create real directories, but I was worried that if they uploaded scripts, that hey could reek havoc on the server.
I am using PHP, and the mkdir() function. Would it be a good idea to use mode 0664 when making directories, to prevent:
Malicious files from being executed.
Prevent just anyone from writing or executing those files.
Is this a good idea?
No, it does not make sense to use 0664 on directories.
You very likely need the X flag on them because you want to be able to get a directory listing. "Executing" a directory has nothing in common with executing a program. Disabling the X-flag on a directory will not affect execution of programs stored inside.
You have identify yourself which account is actually involved with file access. This account might be the owner of some files, and the owner of the directories of these files. Anything PHP does will be done as this user. So it does not matter if you restrict access to the file for the group or the world (aka 0700). On the other hand, your FTP access might not be the same user, but only sharing a group. In this case it is an annoying idea to restrict this group to not having access to the files, because you cannot read, write or delete them.
If you allow users to use an upload facility to your server, and you cannot guarantee that these files will never be executed, you probably shouldn't offer this service. Using access flags will not improve the situation, because PHP does not need the X flag, it only needs the file to be readable. So if the FTP site should be of any use, being able to read the files is a must, otherwise why uploading them?
Note that the usual FTP upload/download service separates uploads from downloads. An upload is a one-way operation that places the file on the server but without being accessible. An administrator has to check the upload and move it into the download area where it is read-only. Nobody can trigger the execution of any file because the server will ignore any executable flags and simply send the bytes of such a file back.
You cannot even open files in a directory without an executable permission. But you can access files in a directory without a read permission. A read permission is needed to list directory contents.
0644 directories are inaccessible except by root.
Examples
Inaccessible:
dir/ = drw-rw-r-- (0644) -- effectively the same as d--------- (0000)
So file_get_contents ('dir/file.txt') will always fail.
Accessible, but no listing possible:
dir/ = d-wx-wx--x (0331)
So file_get_contents ('dir/file.txt') will work if dir/file.txt exists. But opendir ('dir') will not.
Fully accessible:
dir/ = drwxrwxr-x (0775)
file_get_contents ('dir/file.txt') will work if dir/file.txt exists. And opendir ('dir') will return the contents of the directory.
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
I just started working with uploading files via php.
From my understanding you need to set the properties of the folder to 777 so anyone can upload to that location.
That's fine and i only obviously keep information there that is not sensitive, its basically images which are displayed back to the public.
However can someone not just run a delete statement if they know the image name to my server folder or is that only possible if the php file is on my server?
i.e delete myimage.png
Basically my question is other than the normal security precautions like limiting the upload of only .png, using basename etc do i need to take additional security measures to prevent someone deleting files in that folder or can that only be done from a script on my webserver?
I wont be using any post methods to delete images or anything like that but i'm just not sure if its possible to take advantage of a folder with 777 permission and do unauthorized stuff since i gave full access to the folder.
By 777 you're actually giving the read/write/execute access to all the user of the machine where your server lives. Note that this does not mean even website visitors can read/write/execute directly. Its always your webserver (Apache) that does it.
However can someone not just run a delete statement if they know the image name to my server folder or is that only possible if the php file is on my server
If you're PHP scripts have holes then, yes. If your webserver has holes then, yes :)
do i need additional protection on a 777 folder
Yes, you can do with a more restrictive permission. Make the owner of the public upload folder to be apache (mostly www-data), set permissions of just 755, or may be 775 in case even the group wants to write to it.
you can change folder permission 777 to 755 or 744.
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.
I'm working on an upload script for students in my lab class to upload their assignments to a folder inside my home directory. The problem is that the script is run under the user apache and any directories and files created by the script end up owned by that user. In addition the permissions of the folder I wish the files to end up in have to be set wide open so that apache can create directories and move files into it (which of course will still be owned by apache).
I'm trying to replace an old script provided by the department which, among other problems, has about 5 different use cases where the student can receive a confirmation when the file wasn't actually uploaded. That script does use chown apparently without any of the problems PHP has. Perhaps the python interpreter runs with different access setting that the PHP one does.
What tactics are there for handling this?
There's a few ways to cope with this, but the most benign that I can imagine is to dedicated a sub-directory in your home directory for the purpose of uploading assignments.
All you have to do permissions wise is give the directory group ownership by some group the apache user belongs to. Suppose the webserver user is apache, and furthermore there is a group apache said user is a member of. You could also create a common group for this purpose that you and apache are part of.
Now let's say the directory you want to put the uploaded files in is ~/homework-submissions
As yourself
mkdir ~/homework-submissions
chgrp apache ~/homework-submissions
chmod g+a ~/homework-submissions
With this arrangement in place newly created files will be owned by apache:apache, but the webserver should have no problem changing ownership at this point.