PHP file upload - files not readable from /tmp/ in production but they are in localhost

2.4k views Asked by At

I'm stuck on what probably is a file permissions problem. I've spent 10 hours straight on this and I'm at the point of giving up because I literally have no idea how to fix it. My script works perfectly on localhost as well.

I have the following code as part of a file upload script within a controller in my CodeIgniter application:

$this->load->library('image_lib');

$config['upload_path'] = '/tmp/';
$this->load->library('upload', $config);
$this->upload->do_upload("selected_file");

// Variables used later when resizing an image
$originalPostImageFileUploadPath        = $this->upload->data()['full_path'];
$originalPostImageFileUploadFilePath    = $this->upload->data()['file_path'];
$originalPostImageFileRawName           = $this->upload->data()['raw_name'];
$originalPostImageFileExt               = $this->upload->data()['file_ext'];
$originalPostImageFileUniqId            = uniqid();


print_r($this->upload->data());
echo file_get_contents($originalPostImageFileUploadPath);

Here's the output I get when I upload a file:

Array
(
    [file_name] => fosters.jpg
    [file_type] => image/jpeg
    [file_path] => /tmp/
    [full_path] => /tmp/fosters.jpg
    [raw_name] => fosters
    [orig_name] => 
    [client_name] => fosters.jpg
    [file_ext] => .jpg
    [file_size] => 49408
    [is_image] => 1
    [image_width] => 
    [image_height] => 
    [image_type] => 
    [image_size_str] => 
)
<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">

<h4>A PHP Error was encountered</h4>

<p>Severity: Warning</p>
<p>Message:  file_get_contents(/private/tmp/fosters.jpg): failed to open stream: No such file or directory</p>
<p>Filename: ajax/product.php</p>
<p>Line Number: 45</p>

As you can see, the script appears to uploading the file correctly but the file_get_contents() fails because it can't find the file.

What I've tried:

Creating a script with the following code to see if the www-data has sufficient permissions:

echo (is_writable('/tmp/') ? "yes" : "no");
echo (is_readable('/tmp/') ? "yes" : "no");

Both of the above outputs return 'yes' (true)

Changing the chmod of the /tmp/ directory: chmod 777 /private/tmp/ (as bad as this is)

Changing upload_max_filesize to 128M (the file is nowhere near this size)

I've even tried running the following command to see if the file gets uploaded to the /tmp/ directory. It seems it does, but it gets removed in an instant (in less than 0.1 seconds).

watch --interval=0.1 ls 

What else can I try? whoami returns www-data, so am I right in saying something like chown wwww-data /tmp/ should fix the problem? Help

1

There are 1 answers

3
ChrisAdmin On

Usually POSTed file uploads via PHP get sent to a temporary /folder/file and deleted if you don't use the recommended functions, which include: move_uploaded_file() for example my POSTed array has:

name
size
type
tmp_name

I use something like this:

$fileName=$_FILES["resume"]["name"];
$fileSize=$_FILES["resume"]["size"];
$fileType=$_FILES["resume"]["type"];
$fileTmpName=$_FILES["resume"]["tmp_name"];  
$targetFile="/srv/www/uploads/".$fileName;  // Where-ever you want your file to be, you can delete manually later on in the script

/* various checking of size and type etc */

if(!is_uploaded_file($fileTmpName)) {
    echo "Couldn't upload file";
    die(0);
}
if(!move_uploaded_file($fileTmpName,$targetFile)) {
    echo "Couldn't move file";
    die(0);
}

/* now target file exists and stays put */