php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41954 open_basedir and upload_tmp_dir discrepancy
Submitted: 2007-07-10 19:47 UTC Modified: 2007-07-11 16:47 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: nlgordon at iastate dot edu Assigned:
Status: Not a bug Package: Safe Mode/open_basedir
PHP Version: 5.2.3 OS: RedHat Enterprise 4
Private report: No CVE-ID: None
 [2007-07-10 19:47 UTC] nlgordon at iastate dot edu
Description:
------------
When uploading a file in a virtual host that has open_basedir enabled and upload_tmp_dir unset the upload fails.  Documentation claims that move_uploaded_file is open_basedir aware, which might be all well and true, but the file upload it self is not open_basedir aware.  It would also appear that upload_tmp_dir is not open_basedir aware.

I believe I have isolated it down to line 230 of php_open_temporary_file.c in the php_open_temporary_fd function:
<snippet lines="226-235">
	if (!dir || *dir == '\0') {
def_tmp:
		temp_dir = php_get_temporary_directory();

		if (temp_dir && *temp_dir != '\0' && !php_check_open_basedir(temp_dir TSRMLS_CC)) { <--- Problem area
			return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
		} else {
			return -1;
		}
	}

</snippet>

The php_open_temporary_fd function is referenced by the file upload handling code in rfc1867.c  In short the open_basedir check is unnecessary in the case of file uploads since page code can not affect the temp directory uploaded to and move_uploaded_files works correctly.

Reproduce code:
---------------
<?php
if ($_POST['submit'])
{
	echo "<pre>";
	print_r($_FILES);
	move_uploaded_file($_FILES['uploaded']['tmp_name'], '/afs/iastate.edu/virtual/itssilver/WWW/uploads/' .
			$_FILES['uploaded']['name']);
	// move_uploaded_file();
}
?>
<form action="/testing/upload.php"  enctype="multipart/form-data"  name="form_1" method="post">
Upload <input name="uploaded" type="file" size="50"/>
<input name="submit" type="submit" value="Submit"/>
</form>

Expected result:
----------------
$_FILES['uploaded'] should be filled with the information relating to a successful upload.

Actual result:
--------------
Apache error log:

[Tue Jul 10 14:25:07 2007] [error] [client ***] PHP Warning:  Unknown: open_basedir restriction in effect. File(/tmp) is not within the allowed path(s): (/afs/iastate.edu/virtual/itssilver/) in Unknown on line 0, referer: http://silver.its.iastate.edu/testing/upload.php
[Tue Jul 10 14:25:07 2007] [error] [client ***] PHP Warning:  File upload error - unable to create a temporary file in Unknown on line 0, referer: http://silver.its.iastate.edu/testing/upload.php

Also, this error is never sent to the browser, it would appear that the internal engine does not have enough information about the script being run to identify the file even being run in.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-07-11 07:25 UTC] tony2001@php.net
So when upload_tmp_dir is unset and open_basedir is set, PHP tries to autodetect temp dir and ends up with /tmp, which is not in open_basedir.
Hence you get the error which says that /tmp is not in /afs/iastate.edu/virtual/itssilver/.
Did I miss something? Where is the problem here? 
Or you believe that /tmp IS in /afs/iastate.edu/virtual/itssilver/?
 [2007-07-11 16:03 UTC] nlgordon at iastate dot edu
The problem is that move_uploaded_files claims that it is open_basedir 
aware, which I believe, but the php core refuses to upload a file to a 
temp dir outside of the open_basedir restriction.  This sounds like a 
conflict either in documentation or in the file upload process.

I'm not trying to claim that /tmp is within the open_basedir 
restriction, just trying to get some resolution on what is officially 
supported by PHP.
 [2007-07-11 16:20 UTC] tony2001@php.net
>The problem is that move_uploaded_files claims that it is
>open_basedir aware 

move_uploaded_file() is supposed to move this temp file out of the temp dir, but this function is not even called, because the temporary file is (not) written before any function is executed.


 [2007-07-11 16:36 UTC] nlgordon at iastate dot edu
I quote the documentation:

<quote>
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.
</quote>

To me this reads that move_uploaded_file should be able to move a file 
that has been uploaded to a temp dir outside of the open_basedir 
restriction (The part about the restriction ONLY being on the 
destination).  Since open_basedir prevents that from happening you get 
a catch-22 situation.  If I'm wrong and this isn't supposed to happen 
then the documentation needs to be updated to let everyone know that 
they must set upload_tmp_dir if they turn on open_basedir.  This is a 
pretty serious change in functionality and is currently not documented 
anywhere.  So either fix the upload, or fix the documentation.
 [2007-07-11 16:47 UTC] tony2001@php.net
Please re-read my answer:
"..this function is not even called, because the temporary file is
(not) written before any function is executed."
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 03:01:28 2024 UTC