I'm just wanting to confirm that what I'm doing is actually secure.
Firstly, I have a GoDaddy shared hosting account, but I do have a dedicated IP address.
Let's call my server path /path
.
My site's files are located in /path/mysite
When a user uploads a file, I move it to /path/uploads/file_name
.
It is impossible for someone to reach that folder via a URL.
To add, I have a .htaccess file in /path/uploads
with the following:
order deny,allow
deny from all
allow from 1.1.1.1 #let's say 1.1.1.1 is my server's IP address.
And then to actually initiate a download of the file, my users will follow a link to mysite.com/file.php?q=[file_id]
And in file.php
, I download like so:
$mime = mime_content_type($location);
header('Content-disposition: attachment; filename='.$name);
header('Content-type: '.$mime);
readfile($location);
As far as I know, it's not possible for anyone's uploaded files to run on my server, but I may be wrong.
Are there any security gaps that I need to take care of?
First, you don't need the allow from 1.1.1.1
as this will allow you to access this directory via Apache services. No, you will only ever access this directory from an executing program / script.
Second, this is a pretty standard template to address this type of problem. So its well worth looking and widely used packages such as MediaWiki or BB engines such as phpBB approach this and mirror some of their security checks.
My third suggestion picks up the point made by Marc B, you need to think about constraints on the file name and file types that you want to allow / support, and the possibilities of other attacks. One approach is simply to store files with the filename and ascending ID and keep the ID/user filename as a map in a DB table. You also need to think not only about attacks on your server, but that malicious users could use this upload facility to implement XSS and other attacks.
You can disable the PHP interpreter for that directory completely with
php_flag engine off
in your .htaccess. This should give you a good degree of protection against stuff running in that directory.
However, you didn't show your upload code, so it's hard to tell what you are doing there: you really want to check you are not vulnerable to path traversals as that would completely void your protection here.
The download code, too, might be vulnerable: if you are actually using the snippet you posted, the attacker can download any file on your application by simply using "../../whatever.php" as a filename (again, path traversal). Or use that script as a praxy and more - hence you want to make sure you validate the filename value.