PHP open_basedir no effect

6 posts / 0 new
Last post
#1 Wed, 07/08/2015 - 22:13
cerebrum

PHP open_basedir no effect

Hi all,

The PHP directive open_basedir has no effect on our servers. We are using Apache 2.2.x, PHP 5.4.x and FCGI (libapache2-mod-fcgid 1:2.3.6-1.2) on a standard Debian 7.x Wheezy server and virtualmin 4.17.gpl. The following PHP script lists all user directories on the server:

<?php
        header('Content-type: text/plain');
        $command = 'ls -al /home/';
        system($command, $returnCode);
        exit();
?>

in order to prevent this, I activated the open_basedir configuration (set to /home/<user>/www/, which is the DocumentRoot of this web container) in file /home/<user>/etc/php5/php.ini and reloaded/restarted Apache. Function phpinfo() shows that the new setting exists, but the user directories are still listed when I access the PHP script.

I tested other method, such as the following in /etc/apache2/sites-available/example.com.conf to no avail:

php_admin_value open_basedir "/home/<user>/www/" fastcgi_param PHP_VALUE "open_basedir=/home/<user>/www/"

I do not want to switch to mod_php (I would like continue using FCGI). According to this conversation, it should work with php.ini: https://www.virtualmin.com/node/23715

Any idea, what I am missing - or of FCGI bin requires special treatment?

Cheers Michael

Wed, 07/08/2015 - 22:20
andreychek

Howdy,

Which php.ini file is it that you're setting that parameter in?

-Eric

Wed, 07/08/2015 - 23:34
cerebrum

In file /home/username/etc/php5/php.ini:

# grep basedir /home/username/etc/php5/php.ini
; open_basedir, if set, limits all file operations to the defined directory
; http://php.net/open-basedir
; open_basedir =
open_basedir = /home/username/www/

...and phpinfo() shows that the open_basedir setting exists and it shows the correct path. Nevertheless PHP scripts can still read files outside that container.

Thu, 07/09/2015 - 10:07
andreychek

Yeah it definitely can work, and there's a lot of users who mentioned using it in their Virtualmin environments.

Also, you're setting that in the correct file.

That said, I personally haven't done too much with open_basedir in the past, so I'm not quite sure what might be going on there.

Just as a troubleshooting step, you might try setting the PHP Execution Mode to "CGI" in Server Configuration -> Website Options, I'm curious if you see a difference after changing that.

-Eric

Sat, 07/11/2015 - 00:23
cerebrum

Setting PHP execution mode to "CGI" showed the same behaviour. Even when I set it to mod_php... and this made my suspicious :-)

Turned out open_basedir works differently than what I expected:

Commands passed through system() bypass the open_basedir restriction. This is why the PHP code in my original post lists files/directories in /home (no matter if open_basedir is set or not). However you can not change to directory /home using the PHP function chdir() for example (this triggers a warning in error_log: "chdir(): open_basedir restriction in effect. File(/home/) is not within the allowed path(s) [...]").

Another example (for those interested in my findings): create a file with some content as /tmp/secret.txt. In virtualmin, set the open_basedir directive for a domain to /home/user/public_html. A PHP script (e.g. /home/user/public_html/test.php) can still read the content of this file by using:

<?php system('cat /tmp/secret.txt'); ?>

However - with open_basedir restricting access to public_html - the following script fails:

<?php
  $file = file('/tmp/secrets.txt');
  echo implode(PHP_EOL, $file);
?>

Looks like you have to explicitly add system commands to the disable_functions configuration of PHP or use a proper security concept such as http://selinuxproject.org

Other suggestions welcome.

-Michael

Fri, 12/11/2015 - 07:07
rock1982

virtualmin modify-php-ini --all-domains --ini-name memory_limit --ini-value 64M virtualmin modify-php-ini --all-domains --ini-name upload_max_filesize --ini-value 300M virtualmin modify-php-ini --all-domains --ini-name post_max_size --ini-value 300M virtualmin modify-php-ini --all-domains --ini-name max_execution_time --ini-value 60 virtualmin modify-php-ini --all-domains --ini-name open_basedir --ini-value "/home/:/usr/share/:/tmp/" virtualmin modify-php-ini --all-domains --ini-name disable_functions --ini-value pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, show_source, system, shell_exec, passthru, exec, popen, proc_open virtualmin modify-php-ini --all-domains --ini-name expose_php --ini-value Off

find /home -name php.ini | xargs chown root:root

Topic locked