Setting up open_basedir

I strongly recommend configuring the open_basedir parameter, which lists directories beyond which PHP scripts cannot traverse, as open_basedir is not specified by default.
If open_basedir is not specified on the web server, then, for example, Path Traversal vulnerabilities can lead to access to all files on the server that have “read by others” permissions, such as /etc/, /var/, and other directories.

Let’s see if open_basedir is specified:

php -i | grep open_basedir
open_basedir => no value => no value
<?php
var_dump(ini_get('open_basedir'));
?>

I looked at the current session directory:

php -i | grep session.save_path
session.save_path => /var/lib/php/sessions => /var/lib/php/sessions

Now let’s open the php-fpm configuration and specify the required directories:

nano /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[open_basedir] = /var/www/:/var/lib/php/sessions:/tmp

Let’s restart php-fpm to apply the changes:

systemctl restart nginx
systemctl restart php8.3-fpm

That is, I gave an example of a standard /var/www/ with web files and a directory for storing sessions. If PHP scripts access some other directories, then you can see errors about this in the web server logs, and then also specify them in open_basedir.

If Apache2 is used, you can specify it via .htaccess:

php_value open_basedir "/var/www/:/var/lib/php/sessions:/tmp:/ixnfo/com"

There is also an even more secure way to set up chroot, or place the web server in Docker and expose it through an nginx proxy, and you can also set open_basedir for each site individually, so that a vulnerability on one site does not allow access to other sites.

See also my article:
How to set up mTLS

Leave a comment

Leave a Reply