How to secure downloads for authenticated users?

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I have files on my Apache web server that are NOT in publicly accessible space.  
I want to make these files available for download only to authenticated users.

I currently use a download script that is accessed from an SSL-encrypted page  
(that the user arrives at after authenticating).  There are links in this page  
that initiate the different file downloads by passing a variable (name of the  
directory and file) to the download script.

It works fine, but if someone were to guess the full path of the file on the web  
server, the download could be initiated without coming from the SSL-encrypted  
page.  I could check referrer, but I'd rather not rely on that.

How can I ensure that my download script is only initiated from the encrypted  

Here is the download script (which IS in publicly-accessible space):

 $info = trim($_GET['fileinfo']);  //a 'directory.filename.extension' is passed  
 $info_array = explode(".", $info);
 $directory = $info_array[0]."/";
 $filename = $info_array[1].".".$info_array[2];
 $extension = $info_array[2];
 $dlfile = "/home/user-directory/private-data/".$directory.$filename;
 header("Content-Disposition: attachment; filename=".$filename);
 header('Content-type: application/'.$extension);
 header("Content-Length: ".filesize($dlfile));

If someone were to enter a URL like this:

then all the SSL is for nothing...

I could use htaccess to protect the directory that the download script is in,  
but that means the user has to authenticate twice when trying to download  

And if I try to do this:

if ($_SESSION['uid'] == "valid_user")
    //execute script

the download barfs.

How do I make my downloads secure?

Thanks in advance  

Re: How to secure downloads for authenticated users?

I think this is as good as it gets...

An Internal Server Error will be received if 'fileinfo' is passed manually
 to this script (user types the URL with variables). But this protection is
 only available if script resides in /cgi-bin. If this script must reside
 outside of /cgi-bin, try password protecting the directory with htaccess.
 $info = trim($_GET['info']);
 $info_array = explode(".", $info);
 $directory = $info_array[0]."/";
 $filename = $info_array[1].".".$info_array[2];
 $extension = $info_array[2];
 $filedownload = "/home/username/nonpublic/".$directory.$filename;
 header("Content-Disposition: attachment; filename=".$filename);
 header('Content-type: application/'.$extension);
 header("Content-Length: ".filesize($filedownload));

Regardless of where this script resides, I assume the URL (and variables) can  
easilly be sniffed on the wire when the request is made.

Can username/password also be sniffed from user entries in the dialog generated  
by htaccess?  If so, the only way to ensure any security over who downloads what  
is to have this script in /cgi-bin.

Is this correct?

Re: How to secure downloads for authenticated users?

This will not work either, at least not in IE (though it does work in FF):


because, as we all know...

Microsoft Knowledge Base Article 834489 explains that a security update (issued  
back in 2004) has modified the default behavior of Internet Explorer for  
handling user information in HTTP and in HTTPS URLs.

The 832894 security update removed support for handling HTTP and HTTPS URLs in  
the form of:


in Internet Explorer and Windows Explorer. After you install the 832894 security  
update, Windows Explorer and Internet Explorer do not open HTTP or HTTPS sites  
by using a URL that includes user information.;[LN];834489

Site Timeline