Change user PHP - php

I need to change the user of a PHP script at runtime. I've looked at posix_setuid, but it looks unsecure and requires root privaledges. What would be preferable is changing the user id of the script with the users password (something like posix_setuid($username, $password)), and avoiding running the script as root.
I'm open to other methods, and the script doesn't necessarily need to be PHP. However, it is going to be called from apache.
A good anology to the scenario would be how cPanel su's to the currently logged in user on it's file manager.
I need to change the user because I'm creating a file manager for a multi-user setup. Currently, I have the file manager set up so that apache serves my PHP file manager as root. However, this is not reasonable, because in case of a security bug in the code, one user can edit files on the entire server.
I'm looking for a way to SU the script to the logged in user so that in case of a security flaw, the user is only restricted to their own files.

I needed to do this a while ago. I basically created a bash script which accessed resources that only root had access to. Here's what I did:
Use the visudo command to change your /etc/sudoers:
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
apache ALL= NOPASSWD: /sbin/myscript.sh
I have added the line which allows the apache user to run /sbin/myscript.sh with the sudo command without entering the password.
After that, you can just put the following in your php file to get the output:
$output = shell_exec("sudo /sbin/myscript.sh");

This recent question discusses two options for doing this with PHP:
PHP + FastCGI with suexec
suPHP

Related

How do I make the php script work as a superuser

I've assumed that if my php script has permissions set to root, the script would be able to execute commands as a root user. But apparently, it's not the case. I noticed that I cannot write anything outside of www and when I want to write a text file at /test.txt, it won't create a file because of permissions at / saying that non-root users only can access but not create or delete but the script itself has the root permission. If I change permissions at / then it works fine. Why can't my php script, set to have root permissions, write to the / directory?
And what can I do to enable the php script to be executed as a superuser?
I want to use the exec() and I cannot seem to get it to work. I want to be able to create a crontab and it doesn't work. I wrote a code like this:
exec("crontab -l > test.txt; echo '* * * * * echo hi! > /root/Desktop/hi.txt'>> test.txt; crontab test.txt");
But it won't work. If I copy the string into terminal, it works as expected.
Setting the permissions on the script file itself does not affect who the script is run as. it affects who can access the script.
To run the script as root, it depends on the context. Are you running it in a web server or is this a CLI script? If the later, then you must run it while logged in as the root user or with the sudo command. If its in a web-server as apache, then you must configure apache to run as as root but this is highly discouraged as it opens up a lot of security risks.
The permissions/ownership of a script have no bearing on which user that script runs as. It will run as whichever user executes it, assuming it has permission to do so. Sometimes you can use the setuid 'sticky bit' permission to do things like this, but most systems do not allow it, and the least offensive term I can think of to describe allowing it is "inadvisable".
I noticed that I cannot write anything outside of www
Because apache is configured properly. Ideally it will run as a non-root users [usually www] and any scripts will run as that user as well. Instead of telling you how to configure apache to be less secure why not just grant the apache user access to the file/directory that you want to access/modify?

Git WebHook will not pull (PHP)

I have a PHP file, hook.php, that looks like this:
<?php
`cd .. && git pull`;
The file is located in /var/www/oliverash.me/site/. However, the git repository that needs to be pulled is /var/www/oliverash.me/. ./site is the folder Apache looks to as the document root.
When I run the file in my browser, it does not seem to be pulling the repository.
I have also tried to echo the result, but the page is blank.
<?php
echo `cd .. && git pull`;
I can't post a comment in reply to you, but I am assuming that you are running a *nix system. You will be getting a permission denied if your apache/php daemons don't have permission to access .git/. You can change the owner/group of the .git/ directory recursively. Or do a chmod -R o+rw .git/* to give everyone (ie, not owner, not group) access to read and write in the git directory, which should clear up the permissions error that you are getting.
EDIT
Just re-read the question, so what follows probably isn't needed, but leaving it just in case.
Though, doing that, you need to keep in mind that anyone with access to your server will be able to go to http://myurl/.git/ etc to access those. So as a security precaution, I would add a .htaccess file like:
order deny, allow
deny from all
in the.git directory so that apache will deny access from a web browser to everything in there.
You've certainly got a permissions issue, maybe a couple.
The php page is going to execute as the apache user
That user must be able to write to the git repo in question
That user must be able to do the pull in question
You didn't specify what the source of the pull is, but if it's, for instance, a git: or ssh: repo, then that user will need perms (keys, username/password, whatever) to access the remote to do the pull from.
Just saw that it wants /var/www/.ssh - so you're using a ssh:// remote, which is fine, but since it's running as user apache (/var/www is user apache's homedir), it's looking for keys in /var/www/.ssh, which it's not finding, hence the failure. Solutions:
use sudo to switch to a user that does have perms and run the git pull as that user (in your php, do 'sudo git pull', and in your /etc/sudoers put a line allowing user apache to run the 'git pull' command)
set up a .ssh/config file that specifies a Host that's the remote, a User to use to login, and an Identity that is the path to the private key that the remote will allow to ssh in and do the pull.
create webhook.php in the root or anywhere from where you can access it
$result = exec("cd /path/to/repo && git pull origin branch");
make sure the permission is 775 and user of your file and your site directory is www-data owner
You are having a problem with the user here that is executing the command.
According to your various comments, the system commands are executed as the user named apache (homedir is /var/www). You can verify this by running the whoami command from within your PHP script:
<?php echo `whoami`;
That user named apache is commonly the user your webserver runs under, which then runs PHP which then runs the shell commands.
Obviously you want to run the command as some other user, but you have not shared so far the information which one.
Run the shell command under the right user and the problem should go away.
On a linux system, the command to run other commands under a different user is called sudo, another one su:
sudo(8) - Linux man page
su(1) - Linux man page
Alternatively you can make use of suexec to execute PHP under a different user than the webserver user.
In any case you need to ensure that you have a user that is able to execute the git command. I have no clue how you tested that on your own, best way I know is to ssh into the server box, do the git pull manually and collect the needed data like user-name, homedirectory etc. .

php - exec issue

I'm setting up a new server and of course I didn't document every change I did to the last one but I'm getting there.
I have a weird issue, I'm trying to do a simple call in php:
exec('service httpd reload');
And it's not doing anything. I can execute other commands such as tar, I did check php.ini for disabled_functions and it's empty. The username php is using for creating files/folders is "apache" as well.
Does anyone know any other areas I can check? This is a fresh install of php 5.2.x so I'm sure there is a security setting in apache or something blocking this.
Well your apache is most probably running under a normal user account (www-data or apache - it depends on your distribution), but to restart apache (or any other service) you have to be root.
You could use sudo to elevate your privileges.
You can't restart Apache as a normal user, but you should never leave your root password written in a file. If you really have to run that command from php, there's an alternative method.
You can allow certain commands to be run as root by a certain user without specifying a password. To do this you must edit the /etc/sudoers file with visudo and add the tag NOPASSWD to the command you want to run. Here is the example from the man page:
ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
This would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm as root on the machine rushmore without authenticating himself.

CHMOD a linux directory using PHP on an apache server

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.

php - changing file permissions

I have a PHP script which changes file permissions on my server using chmod. I'd like to be able to run the script both via the browser (as nobody) and via a cron job (as username).
Is it correct that only the owner of the file can change the permissions? I.e. if I create a file via a cron job and set the permissions, I can't then change those permissions when running the script from the browser?
Are there any ways round this please? Delete (unlink) and re-create the file as whatever user the script is running as? Or is there a way of running a php script via a cron job as nobody? / via the browser as username?
The aim is to be able to make images publicly viewable or not by changing the file permissions.
Solution 1: Create a group for both the user and the cron user, add each user to your new group, and give both users access to read and write to the file (chmod g+rw filename). (safer then the next solution).
Solution 2: The simplest way to do this is to make the file readable and writable by everybody (chmod a+rw filename) would have this effect.
I would not recommend this for production usage though.
You can do this without putting a username or password in your script.
In your crontab have sudo execute the script as the user that your web server runs as. Following your example, I'll use the nobody user.
0 12 * * * (sudo -u nobody php ./yourscript.php)
Note that the "nobody" user (as well as users like "apache") do not normally have login privileges. This may require you to allow sudo to execute scripts without a tty. You'll know this if you receive an error like: "sudo: sorry, you must have a tty to run sudo"
Allowing this can be done by commenting out the "Defaults requiretty" line using the visudo command. As with any change to sudo, you may want to search for any side-effects this change may come with.
Yes, only the owner of the file can do this. Your options depend on what kind of control you have over the server.
If you have enough control over the server, you can use SuPHP instead of Apache's mod_php. That way, the PHP scripts will be run as the user who owns the script, and any files created by a PHP script will be owned by the same user.
If you don't have that much control (common shared web hosting, for example), you could use something like Joomla's FTP approach. When FTP support is turned on in Joomla, it does all file manipulation using FTP. That way, it can create or manipulate files with the same permissions as the FTP user.
Something like this (error handling ommitted):
$ftp = ftp_connect('localhost');
ftp_login($ftp, 'username', 'password');
ftp_chdir($ftp, '/root/to/website');
ftp_chmod($ftp, 0644, 'filename.ext');
ftp_close($ftp);
Only the owner of the file can do this, I would recommend running the cronjob as 'nobody' instead.
Usually only the owner or the super-user (or equivalent)

Categories