0

I'm using this PHP to upload CSV files:

$mimes = array('application/vnd.ms-excel','text/plain','text/csv','text/tsv');
if ( in_array($_FILES['file']['type'],$mimes)  && ($_FILES["file"]["size"] < 20000)  )
    {
        if ($_FILES["file"]["error"] > 0)
        {
           echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
        }
        else
        {
            echo "Upload: " . $_FILES["file"]["name"] . "<br>";
            echo "Type: " . $_FILES["file"]["type"] . "<br>";
            echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
            echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "csv/" . $_FILES["file"]["name"]);
            echo "Stored in: " . "csv/" . $_FILES["file"]["name"];

        }
    }
    else
    {
        echo "Invalid file";
    }

and it works perfectly on my dev XAMPP setup.

When I deploy the site on the Linux box it behaves as if the file upload is successful but it isn't in the desired folder or tmp folder.

My form is:

<form action="upload_file.php" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="Submit">
</form>

My browser returns from the echos:

Upload: rere.csv
Type: application/vnd.ms-excel
Size: 2.34375 kB
Temp file: /tmp/php5XXT5v
Stored in: csv/rere.csv

I had a friend more familiar with Linux look at this and he has written a few upload scripts. We couldn't figure out a solution.

Any hints?

chris loughnane
  • 2,648
  • 4
  • 33
  • 54
  • 1
    try to chmod 777 csv directory – Ankit Pise Feb 20 '14 at 20:57
  • 2
    Good old W3fools upload script... Enjoy having your server destroyed by the security holes this stuff rips open on your system. – Marc B Feb 20 '14 at 20:58
  • If script does not return "Invalid file", its probably the permissions. Do not do 777 chmod on production, but you have to be sure that the destination folder is writable and executable with www-data (apache2 user). – vekah Feb 20 '14 at 20:59
  • Why don't assign a variable to `move_uploaded_file` and `echo` it... Also, don't trust people that install linux and then use a GUI for help. – Ohgodwhy Feb 20 '14 at 21:02
  • @Marc B Do you agree with this post on a secure way to upload files? http://stackoverflow.com/a/18530956/1265302 – chris loughnane Feb 20 '14 at 22:41
  • 1
    @Ankit Pise chmod 777 csv will work but it's asking for trouble. – chris loughnane Feb 20 '14 at 22:41
  • @vekah As you suggested I think if I change folder ownership to apache it would solve my problem but after reading a few resources I still can't get the right command. Could you post it here please? Thanks – chris loughnane Feb 20 '14 at 22:42
  • No. it's not. "check the mime type sent by the hacker"? Of what possible use would that be? The **ONLY** thing you should use from the $_FILES data is `['error']` and `['tmp_name']`. Everything else is user provided (well, maybe `size` isn't) and potentially forged. – Marc B Feb 20 '14 at 22:44
  • I suggested for 777 to make sure its write permission problem, once confirmed he can try 755 too. – Ankit Pise Feb 21 '14 at 03:53

3 Answers3

1

If script does not return "Invalid file", its probably the permissions. Do not do 777 chmod on production, but you have to be sure that the destination folder is writable and executable with www-data (apache2 user).

Commands for changing permissions are :

chown -R www-data:www-data path/to/writable/dir/

and for make the directory openable :

chmod -R 660 path/to/wrotable/dir/

chmod +x path/to/writable/dir/

EDIT

It depends of your needs. Basically, the users you want to have read/write access to this folder should be add to www-data group. Command : useradd -G www-data users

But you can have some troubles if you create directories or files with another user than www-data. Because the group won't be set to www-data, but of the group of your user. In this case, you have to set acl permissions. If you are in this case, just tell me so, I would help you to set acl :)

vekah
  • 980
  • 3
  • 13
  • 31
  • Thank you @vekah. That is exactly what I wanted. In the command above you made apache group and owner. This works perfectly but it does stop me from listing in directory unless I sudo and it stops me from using ftp to access the folder. Is there a better way to use group and owner. I'm very new to Linux and pointing me in the right direction would be a great help. Thanks. – chris loughnane Feb 21 '14 at 16:55
  • Edited my post for anwser. – vekah Feb 21 '14 at 17:05
0

You should check what return function move_uploaded_file();

 var_dump(move_uploaded_file($_FILES["file"]["tmp_name"]);
 // if return false it can be something with permission on location folder where
 // do you want to store file under linux

from manual php this function return:

 If filename is not a valid upload file, 
 then no action will occur, and  move_uploaded_file() will return FALSE.

 If filename is a valid upload file, but cannot be moved for some reason,
 no action will occur, and move_uploaded_file() will return FALSE. 
 Additionally, a warning will be issued. 
ZiupeX
  • 338
  • 3
  • 13
0

For Ubuntu 14.04 with XAMPP, I also have problem with upload but after I have fixed with sudo chmod -R 777 destination, it works well.

For example:

Temporary folder to upload in my Ubuntu 14.04 XAMPP is /opt/lampp/temp/. If I want my upload files to /opt/lampp/temp/testupload as destination folder, then I need config bellow.

  1. Go to temp folder

    cd /opt/lampp/temp/

  2. Create 'testupload' folder under /opt/lampp/temp/

    sudo mkdir testupload

  3. Change permission 777

    sudo chmod -R 777 /opt/lampp/temp/testupload/

  4. PHP code

    move_uploaded_file($_FILES["file"]["tmp_name"], "/opt/lampp/temp/testupload/" . $_FILES["file"]["name"])

Pao Im
  • 337
  • 3
  • 8