Page 1 of 1

[SOLVED] is_uploaded_file and relative paths

Posted: Tue Nov 10, 2009 8:09 pm
by amadeo
Hi,

I have a problem related to php security measures and relative paths (should I post it in the security section maybe?)

I am uploading files to www.mywebsite.com/tmp_upload/
which is actually /1175/public_html/tmp_upload/

This is a Linux server running PHP. Unfortunately its not really easy to customize and I am not in powers to change it to a better company.

To allow file uploads into /1175/public_html/tmp_upload/, I need to create a php.ini file in /1175/public_html/cgi_bin
Here it is:

Code: Select all

; Whether to allow HTTP file uploads.
file_uploads = 1
 
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
upload_tmp_dir = "../tmp_upload"
 
; Maximum allowed size for uploaded files.
upload_max_filesize = 2M
The files are being sent in correctly, I have a couple of files called like phpWgrkaK which I've sent testing my program. Also, a proof, print_r($_FILES);:

Code: Select all

Array
(
    [uploadedfile] => Array
        (
            [name] => index.txt
            [type] => text/plain
            [tmp_name] => ../tmp_upload/php6VddXd
            [error] => 0
            [size] => 121
        )
 
)
The bad news: I'm in http://www.mywebsite.com/admin_global.php and the returned path to the file is pretty much impossible to reach


I want to move the files to /1175/public_html/uploads. All my .php files are located in the website root, /1175/public_html/
Here are two pieces of code I have prepared for two scenarios. Firstly, do as all tutorials say:

Code: Select all

$target_path = "uploads/" . basename( $_FILES['uploadedfile']['name']); 
move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path))
move_uploaded_file returns false without any warnings:
Warning: move_uploaded_file(../tmp_upload/php6VddXd) [function.move-uploaded-file]: failed to open stream: No such file or directory in /home/1/8/9/1175/1175/public_html/admin_global.php on line 157

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '../tmp_upload/php6VddXd' to 'uploads/index.txt' in /home/1/8/9/1175/1175/public_html/admin_global.php on line 157
So I think, "hey that's easy, i'll just remove the trailing ../"

Code: Select all

$target_path = "uploads/" . basename( $_FILES['uploadedfile']['name']); 
move_uploaded_file(substr(($_FILES['uploadedfile']['tmp_name']), 3), $target_path))
now move_uploaded_file returns false without any warnings. I have read that it means that the security measurements failed. And actually:

For the first scenario, with unreachable path:

Code: Select all

is_uploaded_file($_FILES['uploadedfile']['tmp_name'])
it returns true! Yes, http://www.mywebsite.com/../tmp_uploads/index.txt exists....

For the second scenario where removed the ../ so that I can actually reach the file,

Code: Select all

is_uploaded_file(substr(($_FILES['uploadedfile']['tmp_name']), 3))
returns false and PHP forbids me from moving. It's a good idea from PHP developer since I could move some vital files somewhere else. However, is there any way I can walk around it? Or maybe there is some directive for the php.ini that would fix the relative paths? I guess there must be some trivial answer to this :D

I tried writing in .ini "upload_tmp_dir = "/tmp"" and I've created tmp files with proper permissions everywhere I could, which is /1175/public_html/tmp and /1175/tmp but files could not be saved there (due to UPLOAD_ERR_NO_TMP_DIR)

I would appreciate your help, thank you
Amadeo

Re: is_uploaded_file and relative paths

Posted: Tue Nov 10, 2009 11:48 pm
by requinix

Code: Select all

upload_tmp_dir = "/1175/public_html/tmp_upload"
I would think that's sufficient...

Re: is_uploaded_file and relative paths

Posted: Thu Nov 12, 2009 5:13 pm
by amadeo
Unfortunately, not:

Code: Select all

(
    [uploadedfile] => Array
        (
            [name] => index.txt
            [type] => 
            [tmp_name] => 
            [error] => 6
            [size] => 0
        )
 
)
6 = UPLOAD_ERR_NO_TMP_DIR

Re: is_uploaded_file and relative paths

Posted: Thu Nov 12, 2009 7:47 pm
by requinix
Then it didn't like the temp path you gave. I forget, but #6 might include having the wrong permissions on the upload directly.

Re: is_uploaded_file and relative paths

Posted: Fri Nov 13, 2009 1:01 pm
by amadeo
I guess it would be difficult to determine where it would point. My best guess is that would try the absolute location "/1175/public_html/tmp_upload" on the root of the server.

Anyways, by comparison, even if I knew what folder it was, it would return an error because php script excepts paths to be relative to my php files, why php server expects paths to be relative to cgi-bin directory. That's actually the problem here, if I could add something to the .ini file to change the behaviour. Please take a look:

So, if having upload_tmp_dir = "../tmp_upload" in the ini file results in

Code: Select all

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '../tmp_upload/php6VddXd' to 'uploads/index.txt' in /home/1/8/9/1175/1175/public_html/admin_global.php on line 157
(the server correctly says that the file mywebsite.com/cgi-bin/../tmp_upload/php6VddXd = mywebsite.com/tmp_upload/php6VddXd is legit, but my scripts are looking for mywebsite.com/../tmp_upload/php6VddXd which cannot be reached),

then having

Code: Select all

upload_tmp_dir = "/1175/public_html/tmp_upload"
would result in

Code: Select all

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/1175/public_html/tmp_upload/php6VddXd' to 'uploads/index.txt' in /home/1/8/9/1175/1175/public_html/admin_global.php on line 157
(which my server would translate to exactly mywebsite.com/cgi-bin/1175/public_html/tmp_upload/php6VddXd, and my scripts to mywebsite.com/1175/public_html/tmp_upload/php6VddXd)

So what do you think? I think there is a problem only because the server's basepath for the relative paths is different than of individual scripts'.

Re: is_uploaded_file and relative paths

Posted: Fri Nov 13, 2009 2:12 pm
by requinix
If the path starts with a / then it is not relative. It will not get "translated".
Apparently the full path to the upload directory is /home/1/8/9/1175/1175/public_html/tmp_upload/ - use that.

Re: is_uploaded_file and relative paths

Posted: Mon Nov 16, 2009 9:08 pm
by amadeo
Thank you tasairis, absolute paths work well here!