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//www/, which is the DocumentRoot of this web container) in file /home//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//www/" fastcgi_param PHP_VALUE "open_basedir=/home//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

Howdy,

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

-Eric

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.

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

Setting PHP execution mode to “CGI” showed the same behaviour. Even when I set it to mod_php… and this made my suspicious :slight_smile:

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

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