Has anyone ever used PHP (proven and successful) to CHMOD a directory through a Web Browser?
My roadblocks are:
(a) PHP script runs as "nobody" from the browser
(b) directory above the one I want to CHMOD is owned by the ftp user and "nobody" does not have write permissions to it
So when I try to chmod 0666 /usr/www/dirOwnedbyFTPuser/dirIamTryingToCHMOD/ I get Permission denied
If you have ever written and successfully run a script to do this, can you share the snipit of code with me? Thanks...been at this for months.
Yes it is possible to do this via php. Usual linux permissions rules apply however so as you are looking to chmod scripts not owned by the apache user (nobody) and the apache user does not have write permissions then one method is to give apache permission to use sudo
Be warned - this is potentially a massive security hole!!!
You can give apache permission to use sudo by editing the sudoers file. It is recommended that you do not edit this file directly as an error can leave you completely screwed so on my (Ubuntu) system I type
sudo visudo
Then you need to add a line for your "nobody" user. You can restrict sudo permissions to a particular script or folder so i would recommend writing a shell script to change the permissions and then placing this in a folder away from any other scripts. That way apache doesn't have complete root privileges on your system (which is a pretty scary thought). You can also put some code in the shell script to restrict which files can be changed.
You also need to allow apache to sudo without a password as you have no way of entering the password through php. So the line you would add is something like
nobody ALL=(ALL)NOPASSWD:/path/to/my/script
Then in php you just prefix the command with sudo
passthru ("sudo /path/to/my/script ...");
(there are a few other functions you can use instead of passthru(), was just the first that came to mind)
As I said before, this is potentially very dangerous and whilst the above will work, I have only used it on my own private system before, never on a public production server. I'm sure plenty of people will have comments on the security of this so I would be interested to hear what other potential pitfalls and security holes there could be with this method. I know a similar thing can be done using SuExec but am not so familiar with it so if anyone has any pros or cons of SuExec over this method I would be interested to hear them.
Final note: I would change the apache user from nobody to something like 'apache' or 'www' - probably just being silly but I don't like the idea of giving root permissions to a user called nobody!!!
Hope this helps!
Yes, you can chmod from php via a web browser. (yes we all know it can be a bad idea)..
But - you can only chmod files that the php script has permission to use! if your web server runs PHP as nobody, then you can chmod any files owned by "nobody"...
http://www.php.net/ftp
You could have php log in as the ftp user and do it.
Related
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
Update: turns out the problem is more complicated than I originally thought. I was simultaneously trying to troubleshoot why my mkdir stopped working and it was because I had manually changed permissions of the parent directory to test then switched them back and added a chmod to the script which doesn't work since that one is being run by apache and not myself. I'll be posting a new question with the larger problem as I think adding all of this into this one will become confusing.
I'm a lab instructor at my university and I've been rewriting the script they provide for uploading assignments because the one they have is old and buggy. Instead of modifying the existing script (written in python) I've been writing it from scratch in php.
I've come across an issue where it seems that chown is not working. The php scripts run under the user apache. I'm not sure if that user is 'priveleged' or not but the original script used chown.
Can I assume that therefore apache should have the needed authority and that my issue lies elsewhere or is that faulty logic?
The server is the university's and there is no way they will let me make any configuration changes. I do believe that it is CentOS that they're running. There is no error message i just noticed that I can chmod the file and change the permissions but that the chown command on the next line seems to have no effect.
ls -al on the old scripts show:
-rwxr-xr-x 1 mattw labstaff 5067 Sep 1 17:52 File_Upload.cgi
Doesn't look like the setuid bit is on.
Stefan mentioned "The user apache most likely doesn't have enough permissions to chown a file/folder it does not own". The directory I'm attempting to chown was just created with a mkdir so it should be owned by apache. Should chown work regardless of privilege when you already own the file?
Apache probably doesn't have the privileges to do so. It depends on which environment it's running in. You said apache is running under the user apache, so I'm just going to assume that it's RHEL or a RHEL variant such as Centos.
You would be able to edit the sudoers file (with visudo) and give apache the ability to sudo without a password under a certain directory. Be aware that this isn't recommended if you're very security conscious.
Adding something like
apache ALL = NOPASSWD: /bin/chown 1[1-9][0-9][0-9]\:1[1-9][0-9][0-9] /var/www/[a-zA-Z0-9]*
You may be able to add apache to a different group, or another user to the apache group or something of the sort and chmodding it to 0775 or 0664 instead.
It would be best to post the code that's throwing the error, the error message if any, and which users and groups need access to the files being uploaded.
If the old script is run by the apache user but is able to execute chown it may have the setuid bit on to allow it to run with elevated privileges. In that case your assumption would be wrong.
Please post the output of ls -al /path/to/script to confirm this. It should show root as its owner and a s in its mode.
To enable setuid mode for the new script, chmod u+s it. Do note this may have serious security implications. In particular never leave a setuid script or binary writeable.
The user apache most likely doesn't have enough permissions to chown a file/folder it does not own, you can give apache more rights however this could become a security concern.
It seems i cannot create files. When i set permissions to 777 On the folder i am trying to create a folder in then the script works fine. If the folder is set to 755, it fails. I do not know much about linux, but i am suppose to figure this stuff out. I have spent a couple hours trying stuff. Does anyone know how to make it so that apache has high enough permissions.
I know it is a permissions and apache problem, i just do not know how to fix this. I have edited the httpd.conf file, but i really do not know what i am doing... Any help? (I saved backup.)
Please stop suggesting to use 777. You're making your file writeable by everyone, which pretty much means you lose all security that the permission system was designed for. If you suggest this, think about the consequences it may have on a poorly configured webserver: it would become incredibly easy to "hack" the website, by overwriting the files. So, don't.
Michael: there's a perfectly viable reason why your script can't create the directory, the user running PHP (that might be different from Apache) simply doesn't have sufficient permissions to do so. Instead of changing the permissions, I think you should solve the underlying problem, meaning your files have the wrong owner, or Apache or PHP is running under the wrong user.
Now, it seems like you have your own server installed. You can determine which user is running PHP by running a simple script that calls the 'whoami' program installed in most linuxes:
<?php
echo `whoami`;
If all is right, you should see the username PHP is running under. Depending on your OS, this might be 'www-data', 'nobody', 'http', or any variation. If your website is the only website running, this is easy to change by changing the user Apache runs under. If you have Debian, like I tend to, you can edit the file /etc/apache2/envvars (as root), and change the value for APACHE_RUN_USER. Depending on your OS, this variable might be set in a different configuration file, so if you can't find it in /etc/apache2/envvars, try to search for the variable declaration by using:
$ grep -R "APACHE_RUN_USER=" .
From the directory all apache-config files are in.
If you're not the only one on the server, you might want to consider creating user accounts for every website, and using something like Apache2-MPM-ITK to change the RUN_USER depending on which website is called. Also, make sure that the user the PHP process is running under is the owner of the files, and the directories. You can accomplish that by using chown:
% chown theuser:theuser -R /var/www/website/
If PHP is running with it's own user, and is the owner of the files and directories it needs to write in, the permission 700 would be enough. I tend to use 750 for most files myself though, as I generally have multiple users in that group, and they can have reading permissions. So, you can change the permissions:
% chmod 0750 -R /var/www/website/
That should be it. If you having issues, let us know, and please don't ever take up any advice that essentially tells you: if security is bothering you, remove the security.
I have a similar problem but in my case I have SELinux running and it failed even with 0777 permission. Turns out I need to explicitly allow httpd to have write access on the directory using:
chcon -R -t httpd_sys_rw_content_t <PARENT_OF_MKDIR_TARGET>
SELinux Troubleshooter may have more details.
On ubuntu you edit /etc/apache2/envvars as Berry suggested.
When you change the Apache user, beware of unintended consequences. One of them is the PHP sessions that may be stored in /var/lib/php5. You may need to change the ownership of that folder too.
PHP creates files with apache:apache ownership which seems to be causing issues with other php scripts accessing the file.
How can I allow php to create files with the same ownership as the files that created them?
I've read elsewhere that having safe_mode turned on can affect this but I've turned it off and reuploaded the files and i still get the same issue.
I'm sure this will be a simple question for someone more familiar with apache but I've failed to find the solution by searching around.
Thanks
If ownership matters and multiple users / projects are on the same server, you might want to look into SuExec in Apache: PHP files will then be run by the user indicated in the settings, so default ownership of files is automatically taken care of. It saves a lot of chown/chmod'ing, and the processes run by the user are more easily restricted.
Otherwise, I normally create a group with both the owner & apache, and set the default umask to 007.
If you are using a Windows OS you can start Apache as a service and allow apache to use your own account's permissions when starting.
Try using fileowner ( http://www.php.net/manual/en/function.fileowner.php ) to get the id of the owner of the current script, posix-getpwuid to get the username for that id ( http://www.php.net/manual/en/function.posix-getpwuid.php ) and chown ( http://php.net/manual/en/function.chown.php ) to set the user for the files.
Why go through all the programatic hassle to change the owner? apache.apache is a very insecure owner anyway. Why not just chmod 0777 the file providing read, write, and execute to all owners. This will eliminate the issue.
If you are still having troubles, then you may need to check if open_basedir is on. If that is the case, it is not file ownership or permissions, but location. This basically means you need to put the file in a location that apache/php already has included in their path.
A.M. mentioned chown() above, please be aware that generally chown() can only be used by root and your webserver running account is highly unlikely to be root, that's a very bad idea.
It is possible to setup sudo to allow chown by other users in specific areas and only to specific users. Just have to create a suitable entry in /etc/sudoers, usually by using the visudo program. If you do not have root access yourself, then your hosting provider will have to do this for you, if they will.
For more information: http://www.sudo.ws/sudo/sudo.html
Strangely enough the server can't resize images any more because it doesn't have enough write permissions. When I check the permissions of the directory I want to write my resized images to I see:
username staff
After excecuting echo exec('whoami');
and checking the httpd.conf I saw the user and group for the server was daemon:daemon (this seems to be the default for Zend Server CE on an OSX installation). What should I do so I have enough permissions again. Should I chown my directory to daemon:daemon (what isn't working). Should I change the user of the server or something else?
IMHO there's no point in touching the web server user - it makes sense for Apache to run as a dedicated user and not have access to all your personal files.
The best way to solve this in my experience is to change the file's group to daemon and make it group-writable, but keep you the owner of the file so you can edit / delete it as well. On OS X terminal this is done by:
$ sudo chgrp daemon <file>
$ sudo chmod 664 <file>
Obviously replace <file> with the name of the file you want to give access to.
Another easy way out is to run chmod 666 on the file - make it world writable, but this is not recommended if you care about security in any way (might be ok on your own development environment but never in production or a shared environment).
I really depends on if you are using this in production in the wild or in private. If it were me, I would simply chown the directory for use with the server only. If you give access to that group, you will open up access to many more things.