Jump to content
Sign in to follow this  
Chuckun

Securing your downloadable files with PHP

Recommended Posts

Firstly, a little introduction to these tutorials. I am currently working on a clients website, and when I want to take a break, I've decided I will be posting about techniques I've used to cater for different needs, which people may find interesting.

 

Today, I'll be showing you how you can easily protect your downloadable media.

 

Why would you want to do this? Well, often we want to hide the location of the downloads, to stop people leeching your content. And most measures can be easily swerved.

 

Here is a method I quite like. I have annotated everything for your convenience.

 

Filename: download.php

<?php
$filename = "downloaded.zip"; // this is the fake name you want the downloaded file to be called.
$source = "/downloads/thefile.zip"; // this is the real name and location of the file.

if(file_exists($source)) { // check that the real file exists, if so do the following..

header('Content-type: application/zip'); // set the content type of the current page to the type of file being downloaded
header('Content-Disposition: attachment; filename="'.$filename.'"'); // Forge the download name by setting filename=
readfile($source); // grab the real file to prompt download.

} else { // if the file doesn't exist
echo "Error: File not found!"; // display error message
}
?>

 

So how do we use this? going to the destination: mysite.com/download.php would grab the file 'thefile.zip' from the /downloads/ folder, and prompt you to download it, but with a new name of 'downloaded.zip'

 

This is the simplest version of this method. Obviously with use of $_GET requests you can have download.php choose varying files from the /downloads/ folder. Example below:

 

Filename: download.php

<?php
$id = $_GET['file'];
$filename = "downloaded-".$id.".zip"; // will forge the name downloaded-5.zip (if download.php?file=5 is requested)
$source = "/downloads/thefile-".$id.".zip"; // will pick the real file titled thefile-5.zip (if download.php?file=5 is requested)

if(file_exists($source)) { // check that the real file exists, if so do the following..

header('Content-type: application/zip'); // set the content type of the current page to the type of file being downloaded
header('Content-Disposition: attachment; filename="'.$filename.'"'); // Forge the download name by setting filename=
readfile($source); // grab the real file to prompt download.

} else { // if the file doesn't exist
echo "Error: File not found!"; // display error message
}
?>

 

It gets even more advanced once you start playing with more and more security. When dealing with premium ($$$) content, it's good to use a database and give all your files a masked name, by MD5 encoding the names, storing them in a database with an assigned ID, and having download.php retreive the filename from the database to know which file to retreive. But that'd look a little messy for this tutorial tongue.gif

 

I hope you learned something by reading this..

 

Thanks for reading!

Chuckun

Edited by Fearless Staff

Share this post


Link to post
Share on other sites

Unsure if you'll even see this but this is prone to an RFI (http://en.wikipedia.org/wiki/Remote_file_inclusion) or even more likely a local file inclusion attack given the current state of the code provided. I could simply exploit your $_GET variable and force download your system account usernames and passwords from the server. Of course it is a tutorial but if a user were to have used that code without any knowledge of PHP and simply just c&p, like most do, then I wouldn't advise using it as is.

Edited by Eliel

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×