1

I have a file upload script which will be available to the general public (eg. not a closed work enviorment) and I'm concered about security: I want to allow any file to be uploaded, each file will be uploaded to it's own unique directory, obviously, I can't control if people upload malicious files, but what is the best approach to handle those files?

I thought of:

Removing the extension altogether, and only when serving the files to download, give them their original extension back (because all files names and locations will be saved in db)

Creating a "safezone" to disallow the run of several extensions in the directory.

disallowing the upload of "unsafe" extensions.

ofcourse the problems are: there are way too many "unsafe" file extensions to count them all. one could mask a file as "safe" although it contains some code. and many other security risks...

so... any suggestions?

Itai Sagi
  • 5,537
  • 12
  • 49
  • 73
  • 1
    As long as you control *where* the files go and *who* has access to them after they are uploaded, you can control security. What's the purpose of the site? – Jonathan M Sep 16 '11 at 20:34
  • Loading a file (even a .exe or .sh) to a server, doesn't admit you the rights to execute them. – feeela Sep 16 '11 at 20:36
  • the purpose of this site is to upload files to share. – Itai Sagi Sep 16 '11 at 20:36

5 Answers5

5

For proper safety:

  1. Limit file size
  2. Do NOT ever store the file using ANY user-provided data as part of the file name. Track the uploads via a database and store the file using its associated record's primary key
  3. Do not place the file in a web-accessible directory - allow access only via a script. This script can then fill in the original filename in the download headers.
  4. Wherever you do store the files, store them with non-execute permissions. That means at most 0640 on Unix-ish systems and equivalent on Windows systems.
  5. Throttle uploads to prevent users from filling your system with rips of the latest bluray rip of a summer blockbusters. Throttle downloads to prevent your site from becoming the next warez haven.
  6. Track as much data as possible about your user: at minimum browser ID and their IP addressed. Better yet, require some form of authentication/login before letting them anywhere NEAR the file handling sections of the site.
Marc B
  • 356,200
  • 43
  • 426
  • 500
3

If all you're doing is acting as a file store, what do you care? You're not executing the files or looking at them in any way, are you?

A file extension has nothing to do with how safe a file is.

Edit: What you would really do is store your filename in a database along with a checksum of the full path. Then your script would be passed that checksum, which would then look up in your database, and then you'd return the file somehow. Don't use your webserver to serve up the file, else (as you say in comments below) you could accidentally execute an uploaded PHP file.

CanSpice
  • 34,814
  • 10
  • 72
  • 86
  • but a user can access that file, which will in turn execute itself on my server. – Itai Sagi Sep 16 '11 at 20:36
  • 1
    @Itai: No it won't. I can copy around a malicious file and it won't execute. I can `scp` it to another machine and it won't execute. I can serve it up over HTTP and it won't execute. – CanSpice Sep 16 '11 at 20:36
  • if, let's say that a user upload some thisfile.php which contains a php script, and he'll go to that directory, than correct me if i'm wrong, the file will be executed. – Itai Sagi Sep 16 '11 at 20:38
  • @Itai: Ohh yes, that'll be executed, but you'd want to do this: http://stackoverflow.com/questions/1271899/disable-php-in-directory-including-all-sub-directories-with-htaccess – CanSpice Sep 16 '11 at 20:39
2

Just upload them outside your document root and serve them with a php file when requested

periklis
  • 10,102
  • 6
  • 60
  • 68
2

To prevent server side execution, don't put them into a web accessible folder, but use a script to handle sending the file.

ie:

<?php

// TODO: acl related stuff
// TODO: Map request to file name
// Send the file as an attachment
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $givenFileName . '"');
readfile($realFileName);
rrehbein
  • 4,120
  • 1
  • 17
  • 23
1

I Think you can use this ways to make it secure

1- do not upload the file as its name ( mean you should change the name of the file using md5(rand().time().rand()) ;

)

2- add empty page in dictionary for upload and you can add .htaccess to deny from all you can use read

file to show or download image

3- if allowed to use -> you can rename the dictionary to other name using rename() in php

4- check upload size , and hide all paths by using @include();

5- as @periklis say if you can save the files outside your document root this will help :)

6- deny this extentions .php , .asp .pl .py .rb .htaccess after you strtolower the file extention

SamarLover
  • 182
  • 10