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.
Related
Today I have encountered a strange behaviour which I do not understand.
I am trying to create a directory on the local disk using a PHP 7.0 script using mkdir() function but it produces a "permission denied" error.
In my experience (although very little) this always meant that the user which is executing the PHP script is not authorized to write to the directory. This makes sense to me and is usually not a problem when developing web applications. The default PHP user when using Apache is www-data and I don't encounter problems with it.
In this case though I am using Zend Framework 2 and in particular I am using it's console routes so I am not going through Apache (correct me if I am wrong). I am calling my script as:
php index.php route name [--options]
with my user (which is not root but is a sudoer). The problems start if I output the result of PHP's get_current_user() function because I get 'root' instead of my expected user name. Not only this, but I get 'permission denied' when using mkdir() in the following directory:
drwxr-xr-x 2 www-data www-data 4096 Aug 19 21:21 logs
What I understand from this is that I probably am not the root user as PHP seems to suggest. If I then run the script with 'sudo' in front I am able to create the desired folders but the permissions do not match the ones I specify in my mkdir() function. If I write mkdir('path', 0777) I then get:
drwxr-xr-x 3 root root
This I do not understand. So, if someone could help me figure out what I am doing wrong I would be very thankful. Keep in mind that the fact that I am going through Zend Framework 2 might influence this behaviour (although I am not keen on thinking so).
Thank you in advance for your time.
Edit.
I just realized I didn't tell you what my final goal is so I will now put things in context, sorry.
What I am trying to do is to use this script (run either from root or from my user, preferably from my user) to create these folders inside
/var/www
and to then be able to read and write files (and possibly other folders) to those directories whith the standard PHP user which in my case is www-data
your php runned as apache extension, and using apache permissions.
If you need to create folder as root, you can create cron script for it, which will monitor change in some file, and create directory as root.
Another way to do it, using suid extension, but it a bit complicated.
What permissions do I need to set up on a directory in order to make it writable by php?
By "writable", I mean copying and creation of new files within that directory automatically by php itself.
I'm testing this on a free host, and the default permissions are 755.
When I try executing a php script, that attempts to create another subfolder of that directory, and copy certain files in it, and it fails.
If I set it up to 777, it works fine, but I assume that doesn't work on all Apache versions because of security reasons?
Also, when creating new files, does php act as the "owner"?
Whatever process that runs the PHP interpreter should should have a user account associated with it. Only that user needs write permission in the directory. So to answer your last question, it's usually www-data or apache that is the owner of that file.
Permission of 777 will work because it allows everyone to read, write and execute that directory but depending on your application this might be a security hole.
I'm trying to use this Dagon Design PHP form to help a local non-profit publication enable their readers to submit photos. I've got the "mailer" part working -- the notifications work fine -- but the "saving a file to a folder" part isn't functioning.
On the form page, the author says "the directory must have write permissions," but I'm not sure "who" is writing to that folder -- is this PHP script considered "Owner" when it saves something on my site? Or do I need to allow save permissions for Owner, Group and Others?
I'm not sure why the script isn't saving the photos, but this seems like a good place to start. I've tried looking around on Stack for answers, but most questions seem to have to do with folder creation/permissions.
The page I'm clumsily trying to build is here, if that helps.
As Jon has said already, you don't want to allow write access to everyone.
It's also possible (depending on the hosting) that something like suEXEC is being employed - which will cause your PHP script to run as a user other than the webserver's (as reported by Dunhamzzz).
Probably your best approach, in my opinion, is a script calling whoami:
passthru('whoami');
Or alternatively you could try:
var_dump(posix_getpwuid(posix_geteuid()));
Bear in mind, this does give system information away to the world - so delete the script once you've used it!
Then, as you've correctly asserted in your question, it'll likely be the file permissions.
If you do have CLI access, you can update the permissions safely as so (first command gets the group)
id -n -g <username>
chmod 770 <directory>
chown <username>:<group> <directory>
(You may have to pre-pend "sudo" to the "chown" command above, or find other means to run it as "root"..., reply back if you get stuck.)
If you've not got access to run command-line, you'll presumably be doing this via a (S)FTP client or the alike. I'm afraid the options get a little to broad at that point, you'll have to figure it out (or reply back with the client you're using!)
As always, YMMV.
Finally, bear in mind if this is your own code, people will at some point try uploading PHP scripts (or worse). If that directory is accessible via a public URL ... you're opening the hugest of security holes! (.htaccess, or non-document root locations are your friend.)
If you are not sure how is your server configured (and this would influence who's the final file owner) then add write permission to anyone (chmod a+w folder), upload one file and ls -l to see the owner. Then you can adjust permissions to allow write access to certain users only
The PHP script that saves the files is running with the privileges of some user account on the server; the specific account depends on your OS and the web server configuration. On Linux and when PHP is running as an Apache module this user is the same user that Apache runs as.
Solving your problem reduces to determining which user account we are talking about and then ensuring that this user has permission to write to the save directory (either as owner or as a member of the group; giving write access to everyone is not the best idea).
You'll need to set the permissions of the directory to that of the webserver (probably Apache, nginx or similiar), as that's what is executing the PHP.
You can quickly find out the apache user with ps aux | grep apache, then you want to set the permssions of the upload directory to that user, something like this:
chown -R www-data:www-data images/uploads
I am developing an application which is having 2 servers. The first one is Web Server, where I save my PHP files and another one is File Server where I am storing all the files uploaded by the user.
I want to assign the write permission to directory at runtime so that I can upload the file and after uploading the file I need to change its permission to its previous state.
When I tried chomod(FILE_PATH, 0755). It shows me an error. Assign write permission as root. I have the administrator level credentials of File Server.
What I want is to "Grant permission 777 to the directory by logging in as root at runtime"
Kindly help if there is any code sample available. Thanks in Advance.
You do NOT want to have your server logging in as root. Let me say that again. You really do NOT want your webserver to be logged on as root. If you did that, anyone that got control of PHP could do anything at all on the server. It is seriously unadvisable.
What you want to do is change the owner of the folder to either be the webserver, or assign it into the same group so that the webserver can happily change your folder options and the like.
You can use sudo chown username somedir to change the owner. This article might also help clear up permissions for you.
Edit: Try this blog post for a fairly good broad-ranging article on linux permissions.
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.