Give php permission to create files without permissions error - php

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.

Related

PHP: creates file but can't append with (apparently) correct server permissions (LAMP)

I have seen many questions and answers on this topic but none seem to help my situation. My PHP code is successfully creating a new logfile, but then cannot access that file to append further info, close it, etc.
I am migrating an application from local XAMPP onto LAMP: hence problem only showing up now due to Windows/XAMPP giving no permission troubles.
I started with a default Bitnami LAMP stack, and then manually setup relevant directory permissions on server:
- my sftp user has rwx on htdocs and assorted out-of-web-root directories
- apache is running as 'daemon' so I have given read & execute permissions to relevant directories for 'daemon' as group
- in most directories I have disallowed write permissions for 'daemon'
- however for my (application generated, internal) logs I have a 'logfiles' directory which has rwx for both my user and the 'daemon' group
- 'other' is -rwx for all
When I run my application it falls over pretty much immediately. The error logs showing fopen failed to open stream: permission denied. However, the permissions indicate that it should have access.
When I check the file involved it has following permissions:
-rw-r--r-- 1 daemon daemon 962 Oct 3 10:14 20151003logfile03-10-33530.txt
This tells me that the file was created by Apache (i.e. by my PHP script) and that it has read and write permissions, from when I fopen() with "w"
EDIT: adding directory info:
Folder level permissions give my ftps user and daemon (group) full rwx access:
drwxrwx--- 2 ftpuser daemon 4096 Oct 3 10:30 logfiles
BUT it can't then fopen with "a"
I am assuming that this IS a file permission problem because:
a) it works fine on XAMPP
b) it states permission error in the error log
However, I can't see why it should be a problem, given directly-specified OS-level permissions ... maybe Apache requires an .htaccess 'allow' on this directory also?
Any ideas?
Clarification re why I don't think CHMOD is the answer (sorry #RedAcid):
CHMOD 777 etc is simply a way to set the underlying permissions I already have. Each digit represents 3 binary chars, so 7 is 111 (i.e. read, write and execute). As you can see above, I have read/write/execute for PHP/Apache on folder, together with read/write for file. What I've read suggests that you need execute at directory level, but not at file level because its not trying to execute the file.
So what am I missing here? Why else might it be denying permission?
use chmod 666 for the file and proper user group permissions. folder where files are located must be writable with chmod 777
OK - I found out the problem was higher level parent directory not having read/execute permissions. Now working! (AT LAST!)
For more detail see this previous question:
PHP fopen() fails on files even with wide-open permissions

Why does file_put_contents have permission issues when run from the browser?

This question has been asked a couple of times up here, but I haven't found a solution yet. I have a Fedora 19 LAMP server and I just want to run the simple command: file_put_contents('test.txt', 'Hello there'); in order to confirm that my web server can use PHP to write data to files. I'm having trouble figuring out a proper permissions scheme. To start, just for development, Apache's document root is /var/www/html. This directory was originally owned by a user and group called www-data, but I changed the directory's group to the primary group of the owner of the httpd process, named apache. It is this owner that is active when PHP runs. I've confirmed this with the following:
As you see, the process owner is apache, the current direcory is /var/www/html/php-console. The directory is owned by www-data and members of the group apache have full access to it.
I have tried the following to get PHP to actually create a file in this location, but to no avail:
chmod 777 /var/www/html/php-console
chown apache /var/www/html/php-console
chgrp apache /var/www/html/php-console
cd /var/www/html; > test.txt; chmod 777 test.txt;
Nothing will work while this script is run from the browser. However, when I use file_put_contents with the PHP CLI, it works just like I would expect, provided that the user I'm entering commands as or its group has write permissions to this directory or test file.
So, from the command line, you see how www-data has read, write, and execute permissions to the folder I'm in. posix_getpwuid and posix_geteuid help you to find the owner of the Apache/PHP process, which in this case is the same as the user logged into the console. file_put_contents succesfully writes 8 bytes to the specified file. If I change the group or owner and group to something else, I get Permission denied, which absolutely makes sense.
If this works on the command line, then why not when I really want it to, i.e., while actually serving web pages???
Because you forgot to read the httpd_selinux(8) man page and give the directory the appropriate file context to allow the web server to write files there.

write to a folder and the security risks

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.

Httpd file permission on Apache server

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.

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