I have got directories like /www/site1 and /www/site2 on my server. I would like to prevent files in site1 from executing things like:
include("../site2/configuration.php");
I need the directories to be completely independent.
Run PHP as a user other then the web server user and set the permissions on the directories and files so they can only be access by the owner (chmod 700).
You can use open_basedir php.ini directive.
Related
I am running my server on cPanel.
I have two users accounts:
/home/user1
/home/user2
From user2 I need to include /home/user1/public_html/config.php.
Is their anyway to apply this?
It is fully possible to access php files located in other parts of the hard drive than where the site is run. However, this depends on two things. First of, the web user needs read permissions for the file, and you need to define the root folder where that php file is located as a accessable folder for the website.
Setting file permissions for the file can be done with:
chmod +R 775 /home/user1/public_html/config.php
Defining the accessible folders for PHP depends on wether you are running Apache or Nginx.
In Nginx for example:
fastcgi_param PHP_ADMIN_VALUE "open_basedir =$document_root:/tmp:/usr/local/lib/php:/var/www/vhosts/yourdomain/httpdocs/:/home/user1/public_html";
In Apache:
Apache readme
Now you should be able to require the file like you normally would require any file:
require('/home/user1/public_html/config.php');
Why not just copy paste the /home/user1/public_html/config.php file to /home/user2/public_html/? If you don't have permissions to access or do any operation on the file, then you are simply not authorized to attempt this.
THE SITUATION
I have multiple folders in my /var/www/ directory.
Users are created that have control over a specific directory... /var/www/app1 belongs to app1:app1 (www-data is a member of the app1 group).
This works fine for what I want.
THE PROBLEM
If the app1 user uploads a PHP script that changes the file/folder permissions for something in app2s directory structure, the Apache process (as there's only one installed on the server) will be more than happy to run it, as it has the necessary permissions to access both /var/www/app1 and /var/www/app2 folders and files.
EDIT:
To the best of my knowledge, something like, /var/www/app1/includes/hack.php:
<?php
chmod("/var/www/app2", 777);
?>
The Apache process (owned by www-data) will run this, as it has permissions to change both /var/www/app1 and /var/www/app2 directories. The user app1 will then be able to cd /var/www/app2, rm -rf /var/www/app2, etc., which is obviously not good.
THE QUESTION
How can I avoid this cross-contamination of the Apache process? Can I instruct Apache to only run PHP scripts that affect the files/folders that reside within the relevant vHost root directory and below?
While open_basedir would help, there are several ways of bypassing this constraint. While you could break a lot of functionality in php to close off all the backdoors, a better solution would be to stop executing the php as a user whom has access to all the files. To do that, you need to use php-fpm with a separate process pool/uid/gid for each vhost.
You should still have a separate uid for the php execution from the uid owning the files with a common group allowing a default read only access to the files.
You also need to have separate storage directories for session data.
A more elaborate mechanism would be to use something like Apache traffic server in front of a container-per owner with each site running on its own instance of Apache - much better isolation, but technically demanding and somewhat more resource intensive.
Bear in mind, if you are using mariadb or similar, that the DBMS can also read and write arbitrary files (SELECT INTO OUTFILE.../LOAD DATA INFILE)
UPDATE
Rather than the effort of maintaining separate containers, better isolation could be achieved with less effort by setting the home directory of the php-fpm uid appX to the base directory of the vhost (which should contain, not be, the document_root - see below) and use apparmor to constrain access to the common files (e.g .so libs) and #{HOME}. Hence each /var/www/appX might contain:
.htaccess
.user.ini
data/ (writeable by fpm-appX)
html/ (the document root)
include/
sessions/ (writeable by fpm-appX)
You should add an open_basedir directive to each site's vhost file. The open_basedir directive limits the directories that a site can access.
You can read more about open_basedir here.
I have a bunch of PHP scripts inside of, say, /public_html/mydir/, and these scripts may possibly try to delete files / do other stuff to the filesystem.
I want to allow all filesystem modifications within the /public_html/mydir/ directory, but any access (or deletion) outside of the mydir directory shouild not be allowed.
How can I do this?
You either make a user that only has permission to access these directories, or you have to somehow run PHP in a sandbox like chroot
Seems it is a question about .htaccess, not sure what should I use.
How can I make files inside /data/ folder available to read and write only for scripts?
Users should not have access to them from browser window.
Simplest way to block access to non-scripts: move it outside the web server's document root. If your PHP files are served from /var/www/htdocs, put your data files in /var/www/data.
If that's not possible, the .htaccess solution looks like:
# don't let anyone access these files directly
Order allow,deny
Deny from all
You can change the ownership of the directory to the www or apache user, depending on what user your web-server is running as.
Then make sure that the permissions of the directory are set to 644 so that only the owner can write. If you want nobody else to be able to read, just make it 600.
Im making sort of a service where people can upload PHP files and they get their own directory.
Is there a way to prevent any way the PHP can access the root of the server? and just stay in the bounderies of its folder?
The open_basedir directive does just that :
Limit the files that can be opened by
PHP to the specified directory-tree,
including the file itself.
The most secure would be to chroot Apache and PHP.