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
page?
Here is the download script (which IS in publicly-accessible space):
$info = trim($_GET['fileinfo']); //a 'directory.filename.extension' is passed
in
$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));
readfile($dlfile);
If someone were to enter a URL like this:
http://www.example.com/download-script.php?mydirectory.myfile.zip
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
something.
And if I try to do this:
session_start();
if ($_SESSION['uid'] == "valid_user")
{
//execute script
}
else
{
exit;
}
the download barfs.
How do I make my downloads secure?
Thanks in advance
/*
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));
readfile($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?
header("Location:https://$username:$pass...@secure.example.com/username/mydirectory/download-script.php");
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:
http(s)://username:password@server/resource.ext
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.
http://support.microsoft.com/default.aspx?scid=kb;[LN];834489