php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38934 move_uploaded_file() cannot read uploaded file outside of open_basedir
Submitted: 2006-09-23 11:36 UTC Modified: 2012-05-09 06:04 UTC
Votes:6
Avg. Score:4.8 ± 0.4
Reproduced:6 of 6 (100.0%)
Same Version:2 (33.3%)
Same OS:2 (33.3%)
From: ofawc5j0lhd9uab dot 8 at gmail dot com Assigned: rasmus (profile)
Status: Closed Package: *General Issues
PHP Version: 5.1.6 OS: Ubuntu 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: ofawc5j0lhd9uab dot 8 at gmail dot com
New email:
PHP Version: OS:

Further comment on this bug is unnecessary.

 

 [2006-09-23 11:36 UTC] ofawc5j0lhd9uab dot 8 at gmail dot com
Description:
------------
According to the documentation PHP should be able to read 
the uploaded file, although it's outside the open_basedir 
directories:
"""
Note:  move_uploaded_file() is both safe mode and 
open_basedir aware. However, restrictions are placed only 
on the destination path as to allow the moving of uploaded 
files in which filename may conflict with such 
restrictions. move_uploaded_file() ensures the safety of 
this operation by allowing only those files uploaded 
through PHP to be moved.
"""

However, I have to add /tmp to open_basedir - which is bad 
in terms of users would be allowed to access the files 
there!

I've not explicitely set the upload_tmp_dir directive, so 
the default "/tmp" gets used.

See also these old bugs, where it seems to have been 
fixed, but now is broken again:
http://bugs.php.net/bug.php?id=21885
http://bugs.php.net/bug.php?id=27559

Reproduce code:
---------------
upload.php file:
<?php

error_reporting(E_ALL);
ini_set('display_errors', 'on');

if( empty($_FILES) )
{
?>
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="upload.php" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

<?php
}
else
{
        $uploadfile = dirname(__FILE__).'/upload_file.test';
        echo '<pre>';
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
                echo "File is valid, and was successfully uploaded.\n";
        } else {
                echo "Possible file upload attack!\n";
        }

        echo 'Here is some more debugging info:';
        print_r($_FILES);

        print "</pre>";
}

?>


Expected result:
----------------
File upload.

Actual result:
--------------
Warning: move_uploaded_file() 
[function.move-uploaded-file]: open_basedir restriction in 
effect. File(/tmp/phpoNSKDN) is not within the allowed 
path(s): (/XXX) in ...

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-09-25 11:19 UTC] Bjorn dot Wiberg at its dot uu dot se
Same result on IBM AIX 5.2 ML8, although I'm using PHP 5.1.5 (no big difference) and have "php_admin_value upload_tmp_dir none" set (so it defaults to /tmp).

---8<---
Warning: move_uploaded_file(): open_basedir restriction in effect. File(/tmp/phpP5moMa) is not within the allowed path(s): (.:/apache/php/lib/php/:/apache/htdocs/bwiberg/) in /apache/htdocs/bwiberg/test/safemode/upload.php on line 9
--->8---

As you can see, /tmp is not within open_basedir, but I think it should not need to be...

---8<---
<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/apache/htdocs/bwiberg/test/safemode/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
   echo "File is valid, and was successfully uploaded.\n";
} else {
   echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";
?> 

--->8---

Best regards,
Bj?rn
 [2006-09-25 12:54 UTC] tony2001@php.net
Cannot reproduce with both 5.1.6 and latest CVS.
With upload_tmp_dir not set (aka "/tmp") and open_basedir="/www", I get this: File is valid, and was successfully uploaded.
 [2006-09-29 18:12 UTC] moron at industrial dot org
Exact same behaviour with 4.4.4 under FreeBSD 6.1. 

Frustrating as this bug has appeared before.
 [2006-09-29 18:13 UTC] moron at industrial dot org
Sorry, forgot to note that in our case, "upload_tmp_dir" is explicitly set.
 [2006-09-29 18:29 UTC] moron at industrial dot org
Sorry for the flurry.  In our case it turned out that the error message was just misleading.  A simple permissions issue on the target directory was the cause (arrgh) but the error message explicitly stated that the problem was the open_basedir setting of the upload_tmp directory.  So more of an annoyance than a show stopper in our case.
 [2006-09-30 15:25 UTC] phpbugs at thequod dot de
Just tried it with PHP_5_2 (CVS), resulting in:
Warning: Unknown: open_basedir restriction in effect. 
File(/tmp) is not within the allowed path(s): (/var/www) 
in Unknown on line 0
 
 Warning: File upload error - unable to create a temporary 
file in Unknown on line 0


I've configured PHP just 
with "--with-apxs2=/usr/bin/apxs2" and use this simple 
php.ini file:
open_basedir = "/var"
display_errors=on
display_startup_errors=On
error_reporting=E_ALL
 [2006-10-02 09:28 UTC] tony2001@php.net
Reclassified as docu problem.
upload_tmp_dir must be in open_basedir() to be readable/writable.
 [2006-10-02 20:03 UTC] phpbugs at thequod dot de
Since when? As far as I understood, you have expected it 
to work like this (when trying to reproduce it).

Also, from older bug reports, it had been fixed to work 
like this again.

Additionally, from a security perspective, it would open 
up the upload_tmp_dir for all processes sharing the same 
php.ini/upload_tmp_dir and you would have to manually set 
it for every vhost where you use open_basedir for to an 
own directory.

If it's supposed to stay a documentation problem, please 
emphasize it in the NEWS/upgrade docs, because as it is 
now (e.g. failing since 5.1.6), it will break all upload 
scripts for hosts that use open_basedir.

IMHO it should work just like expected: PHP should 
internally allow the temporary uploaded file to get stored 
in upload_tmp_dir and should allow move_uploaded_file() to 
move it - PHP should know that it has to make an exception 
here to the regular open_basedir restriction (and it 
seemed to have done so before).
 [2006-10-03 11:54 UTC] youza at post dot cz
See this bug -  http://bugs.php.net/bug.php?id=37236
not any response from PHP :-)))
 [2006-10-13 01:44 UTC] iliaa@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.


 [2006-10-13 09:50 UTC] phpbugs at thequod dot de
It seems to have been fixed in CVS for PHP_5_2 and HEAD 
(but not PHP_5_1).
Seems like iliaa has just used the wrong text snippet when 
closing the bug.

Thank you!
 [2012-05-09 06:04 UTC] rasmus@php.net
-Assigned To: +Assigned To: rasmus -Block user comment: No +Block user comment: Yes
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC