Creating a SECURE file manager with PHP
(Page 1 out of 3)Introduction
This is a follow-up tutorial on "Creating a file manager with PHP", and I highly recommend reading the previous tutorial first, before reading this tutorial.
In the previous tutorial I showed you how to build a simple file manager, which could upload, download, edit and delete, with PHP, but there was one problem: it wasn't completely secure if you had your upload directory in a public place. That's why in this tutorial I'm going to show you how to fix that.
The big problem about having your upload directory in a public place is that it's possible for visitors to directly access the files. Now imagine someone uploading a PHP script, and then visiting the file they uploaded: It gets executed as a normal PHP script, and this means full access to your server, and the real possibility to cause some serious damage.
This is quite a bad situation, so that's why we'll be closing that security hole in this tutorial. Let's start by thinking of a solution.
Thinking of a solution
The problem is that the files shouldn't be directly accessible. What possible solutions are there?
The easiest way would be to move the upload directory above the web root, which means it won't be accessible by visitors, but let's have a look at creating a PHP-based solution.
The first solution that comes to mind is adding our own extension to each file, making it impossible to run any PHP scripts. For example, myscript.php is stored as myscript.php.bak, which means it won't get executed by the web server as a PHP script.
But this still gives visitors the possibility to view and download files by having a look in the upload directory. We're looking for a solution that forces them to use our streaming feature.
Another solution that springs to mind is using a MySQL database, where we will store all the files. This meets our requirement, as visitors must use our streaming feature to download the file, because the file only exists in the database. The only downside of this solution is that it stores all the files in the database, which means the size of the database will explode, and it makes our file manager just a little bit slower. So that's not the solution we're looking for either.
The best solution is to encode the file, making it impossible to be viewed directly, but still possible to be downloaded through the file manager. The easiest way to do this is to change the file into a PHP script, and attaching the following line at the top of every file:
This line makes sure that the file can't be viewed directly, but can still be opened by our file manager. The actual file data will also be encoded using the base64_encode() function so nothing harmful can be passed.
Let's start implementing this feature in our file manager. If you're still unsure about what I mean, don't worry, as you'll soon understand.
February 22nd, 2006 at 8:56 pm
Sexy, just getting started with the whole web development thing, very excitng. i enjoyed this tutorial.
February 22nd, 2006 at 11:01 pm
Just wondering if i might get a response on this question. I get a security error when i try to do anyhting with the files, be it edit, or delete, or download. ID this due to folder restrictions, i have the permissions at 777. or should i try locating the uploads folder above my web directory as you stated in this tutorial?
April 4th, 2006 at 8:24 pm
What if instead of downloading the file, I want to use the file as an image source? For example: img src=’uploaded_file.php’ ?
August 1st, 2006 at 10:07 am
thanks very much i got a way for security purpose in files .
but can you tell me how we can upload mpeg files
August 11th, 2006 at 9:16 pm
For PHP 4.3 and higher, you can use file_get_contents() to get the file contents as a string instead of having to use implode() with file().