"exec('sh foo.sh')" in PHP not working - php

I've recently set up my Apache2 Server on my Linux machine. Now I've wanted to execute a PHP script (index.php), which runs a shell script (foo.sh), which creates a folder in my home directory, but the directory was not created.
These are the original two files:
foo.sh:
#!bin/bash
mkdir /home/lorenzo/testDir
index.php:
<?php
exec('sh test.sh');
?>
So, I thought maybe the problem occurs because of privileges or something, and indeed after I changed the files to that:
foo.sh:
#!bin/bash
echo "Hello world"
index.php:
<?php
$temp=exec('sh test.sh');
echo $temp;
?>
I saw the output Hello World on my website.
So the PHP script is executed and it runs the shell script. But why can't the shell script execute the mkdir command?

This indeed is most likely a permission issue.
You first have to figure out which user apache runs at. This is usually www-data (on Debian-ish Linuxes, such as Ubuntu) or apache (on RedHat-ish Linuxes) or something along the lines. A ps -eF | grep apache will reveal the user.
After you figured that out, make sure that the apache user has the appropriate rights in your home directory. You can either add it to your user group (using usermod -a -G ... and then chmod g+w ~) or allow writing for all users (chmod o+w ~).
But, both of this is a bad idea. Your php script (or anything else running as the apache user) can be broken into and cracked, leaving you home directory open for malicious attackers to modify and rm -rf.
In addition, if you’re running a RedHat-ish Linux, you will run into SELinux which by defaut prevents apache from accessing user directories at all. In that case, you also have to set setsebool -P httpd_enable_homedirs on.
Instead, I would recommend that you use a different directory and give your user full access to that. Something along the lines of /var/www/testDir with the apache as owner and group, and adding yourself to the apache user group is probably a sane idea.

It looks like a permission issue. Make sure that Apache has write permission to that directory

You may have permission issues on the server. Try to use chmod -R 775 <dirname>(or 777) in your ssh command line. You can do this in php code with chmod() too but I don't suggest you because it would run it everytime the php code runs and changing it more times is pointless. It can output to the screen but I bet the directory the script wants to make file has permission 755. Try to check it.

Related

What permissions are needed to write to folder outside of webroot?

I am using nginx with an install of Wordpress; I was trying to come up with a way to store user uploads beyond the web root and use a php script to serve them when needed.
I am positive I will need to log in as root on the server to accomplish the right settings; but I do not know the right way to set permissions for nginx to allow a php script to write to the folder and access it's contents.
My path to the web root looks like this:
/var/www/vhosts/mydomain.com/httpdocs
So I wanted to create a folder here ( I am guessing ):
/var/www/vhosts/mydomain.com/new_folder
I have not logged in to the server as the root user before, but I have found a few lines of commands that may be relevant. I do not know which applies to my situation.
mkdir /var/www/vhosts/mydomain.com/new_folder
chmod 755 /var/www/vhosts/mydomain.com/new_folder
Will this work for a server running nginx? or do I need something like this?
mkdir -p /var/www/vhosts/mydomain.com/new_folder
sudo chmod -R 0755 /var/www/vhosts/mydomain.com/new_folder
I think that the sudo command deals with permission on folders that were supposed to only be accessed by the root user.
I am having a hard time researching this as I do not understand which context to use these commands. I still do not know how to set the permission of a folder so a php script can read and write to that directory.
I could really use a nudge in the right direction, as I am terrified in trying to just start blindly entering commands on the server logged in as root.
I'm not a nginx expert, I'm used to apache, but my guess is all you need to do is make sure the user that nginx is running under has write permission to a folder. In order for this command to word:
mkdir /var/www/vhosts/mydomain.com/new_folder
You need to make sure you are logged in as a user that has write access to /var/www/vhosts/mydomain.com/. If your normal user doesn't have the permission that is where sudo comes in. sudo basically means run this command as root. It should also ask you for your root password when this is done. You can add sudo in front of any of the commands listed above or below if you don't have sufficient permission to do something.
This command is creating a new directory/folder mkdir = make directory. This command:
chmod 755 /var/www/vhosts/mydomain.com/new_folder
Is changing the permissions on that folder you just created. You can do some research and see what 755 stands for. More importantly though you will probably need to use the chown command to give ownership of the directory to the nginx user. As I said I'm not a nginx user so I don't know what the standard username is, but for apache it would look something like this:
chown www-data:www-data /var/www/vhosts/mydomain.com/new_folder

php script to execute python script to write some files

I have a php script that calls a python script which in turn is in charge of writing some files to disk.
If I execute the php script by entering its url in the web browser it can perform several filesystem related tasks:
it's able to create a dir
it's able to chmod the dir
but it's not able to execute the python script which would create and write other files.
The strange thing is that if I run the python script manually as www-data:
user#host $ sudo su www-data
passwd for sudo:
$ whoami
www-data
$ python my_script.py
It works like a charm.
I'm assuming the user when I run the script through the browser is www-data. So why is the result in the console any different?
SOLVED:
Python script starts off by importing some modules from my repository, which are appended to the path via .bashrc or .bash_profile on login consoles. These modules were not available from the browser to the user www-data. So adding this to the python script solved it:
import sys
sys.path.insert(0, 'path_to_my_modules')
solved it.
I apologize for the question. It didn't bring all the necessary information for users to lead to a solution. I guess the problem was so broad that it was difficult for me to start thinking of where its root was.
I lacked a good debugging technique to see what the error was. I commented out all the python script and begun with a simple print 'here'. Uncommenting lines one by one showed me the place where it just didn't print anything anymore (the error was obvious then).
First of all, don't assume that the user is www-data. You should get the output from whoami running from the PHP script to see if it is www-data. Also, you need to make sure your script has +x or execute permissions for the user.
You should read about execute permissions.
You need to use chown on your PHP script to change the ownership to the www-data user:
sudo chown www-data:www-data yourscript.php
Then you need to give the user execute permissions:
sudo chmod u+x yourscript.php

Executing a bash script from a web page via PHP's shell_exec(), which requires another user's perms?

I have a couple of bash scripts on a Centos box which I use to do basic server admin stuff like restart services, etc. I run these as a standard user who is also the scripts' owner.
I tried to run these using shell_exec() in PHP, with the apache user, but it simply doesn't work - I'm guessing it doesn't have enough permissions (even with 775 and being in the correct group!) to run everything I want it to.
I've tried editing the sudoers file giving apache permission to run the script calls but it still doesn't work and has no error messages that I can see.
Any thoughts? How can one trigger a script from a web page which requires a different user to run?
check under which user is running apache ( for debian it is www-data)
add www-data in sudoers list with permission to execute files that you like
check which shell has www-data user in /etc/passwd (you will need to give valid shell)
run script with /bin/bash -x (it will output for sure)
Make sure safe mode is off. Also verify the user is the one you expect:
<?php echo exec('whoami'); ?>

chown in scripts

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.

function.fopen: failed to open stream: Permission denied in PHP

I'm trying to create XML sitemaps for my website from my PHP application. The idea is to either create a new file or overwrite an existing file. When I call fopen, I get the following error:
[function.fopen]: failed to open stream: Permission denied
I'm trying to write to the webroot and its permissions are: 755. This means that the owner has write permission, right? What do I need to do to make my script be able to write to this folder? 777 would be a bad thing, right? Can I run my script as owner somehow?
Thanks.
Yep, as you've said, using 777 could be huge mistake. The webserver doesn't run with the same user as you use to create files and folders.
You have some options:
Run the sitemap creation as a cronjob, using an user with rights to write there, other than the apache user.
Put the sitemap in another directory, and the set up a 302 Redirect or a symlink. In this case, if you have a security issue that let's someone to write your sitemap.xml, at least they'll not be able to create another file with a more dangerous extensions (like PHP, which may result in a site intrusion).
Make a rewrite rule to redirect any hit to sitemap.xml, to a php script that outputs the appropriate XML.
Good luck!
I'm a beginner and I had this problem as well. I am using Ubuntu linux w/ php and apache
Write a php script w/ the following: <?php exec('whoami'); ?> and run it on your server. This tells you who the current user of the script is
SSH to your server.
Make a group that has read and write access to the files you need.
Make group have read, write, and execute on folders you need.
Make the current user you found in the first step, part of the group that has access to the files you need.
Restart Apache: sudo apachectl restart
main commands you need are:
groupadd: Create a new group
usermod: add your user to a new group
chgrp: changes files / folders to group you specify
chmod: changes permissions on the files / folders you specify.
All the commands you need are here: http://www.yolinux.com/TUTORIALS/LinuxTutorialManagingGroups.html
If you have ACL enabled on the webroot partition just grant the web server username full rights
setfacl -m u:apache:rwx /var/www/html
Replace apache with the web server username and /var/www/html with your webroot location.
had the same problem
Looks like apache is running as nobody in the nobody group
so if you do a
useradd -G nobody youruser
chown -R youruser:nobody .
Then change the permission to 0775
chmod -R 0775 .
or you may add nobody to your usergroup
useradd -G nobody yourgroup
this be a better solution
Does it work with group write enabled (i.e. 775)?
Check your group permissions for the directory the file is in. As long as your PHP user (usually www-data) is part of that group, and it's the only user, you should be fine with 775 (or even 774).
Like Pascal said!
just find your apache user
<?php exec'whoami'; ?>
and then
useradd -G username username2
chown -R username:username2 .
chmod -R 0775 .
And its done!
Thank you Pascal!
777 is pretty normal, because PHP does not run as you, it runs as a PHP user, Apache, etc. The fact is, your webhost should have a higher set of permissions that prevents other users from writing/deleting your files.

Categories