Jump to content

Hiding file path help


WOPR

Recommended Posts

I'm trying to use a download.php script to hide the directory where the files I am going to serve are located.  This seems like it should be a relatively simple task but for some reason this is just absolutely confounding me....it's been a while since I messed around with php so it's probably something stupid that I am missing but so far for the life of me I can't figure out the problem.

 

Here's what I've got in my download.php script (one that I found by googling):

 

<?php
// Usage: <a href="download.php?file=captcha.png">Download[/url]
// Path to downloadable files (will not be revealed to users so they will never know your file's real address)
$hiddenPath = "http://www.themeinerz.com/dl_files/ut3/maps/pc/";

// VARIABLES
if (!empty($_GET['file'])){
$file = str_replace('%20', ' ', $_GET['file']);
$category = (!empty($_GET['category'])) ? $_GET['category'] . '/' : '';
}
$file_real = $hiddenPath . $category . $file;
$ip = $_SERVER['REMOTE_ADDR'];

// Check to see if the download script was called
if (basename($_SERVER['PHP_SELF']) == 'download.php'){
if ($_SERVER['QUERY_STRING'] != null){
// HACK ATTEMPT CHECK
// Make sure the request isn't escaping to another directory
//if (substr($file, 0, 1) == '.' ¦¦ strpos($file, '..') > 0 ¦¦ substr($file, 0, 1) == '/' ¦¦ strpos($file, '/') > 0)  {
if ((substr($file, 0, 1) == '.') || (strpos($file, '..') > 0) || (substr($file, 0, 1) == '/') || (strpos($file, '/') > 0))
{

// Display hack attempt error
echo("Hack attempt detected!");
die();
}

//--------------------DEBUG-----------------------

          echo "file is: $file
";
          echo "file_real is: $file_real
";
             
          echo "POST:";
          print_r($_POST);
         
          echo "GET:";
          print_r($_GET);

//--------------------DEBUG-----------------------

// If requested file exists
if (file_exists($file_real)){
// Get extension of requested file
$extension = strtolower(substr(strrchr($file, "."), 1));
// Determine correct MIME type
switch($extension){
case "png": $type = "video/x-ms-asf"; break;
case "avi": $type = "video/x-msvideo"; break;
case "jpg": $type = "application/octet-stream"; break;
case "jpeg": $type = "video/quicktime"; break;
case "mp3": $type = "audio/mpeg"; break;
case "mpg": $type = "video/mpeg"; break;
case "gif": $type = "video/mpeg"; break;
case "rar": $type = "encoding/x-compress"; break;
case "txt": $type = "text/plain"; break;
case "wav": $type = "audio/wav"; break;
case "pdf": $type = "text/plain"; break;
case "doc": $type = "audio/wav"; break;
case "jpeg": $type = "text/plain"; break;
case "bmp": $type = "audio/wav"; break;
case "wma": $type = "audio/x-ms-wma"; break;
case "wmv": $type = "video/x-ms-wmv"; break;
case "zip": $type = "application/x-zip-compressed"; break;
default: $type = "application/force-download"; break;
}
// Fix IE bug

*

$header_file = (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ? preg_replace('/\./', '%2e', $file, substr_count($file, '.') - 1) : $file;
// Prepare headers
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public", false);
header("Content-Description: File Transfer");
header("Content-Type: " . $type);
header("Accept-Ranges: bytes");
header("Content-Disposition: attachment; filename=\"" . $header_file . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($file_real));
// Send file for download
if ($stream = fopen($file_real, 'rb')){
while(!feof($stream) && connection_status() == 0){
//reset time limit for big files
set_time_limit(0);
print(fread($stream,1024*Cool);
flush();
}
fclose($stream);
}
}else{
// Requested file does not exist (File not found)
echo("Requested file does not exist");
die();
}
}
}
?>

 

What I have then at the moment for testing is simply a blank index page with an a link passing in the file name like this:

<a href="download.php?file=CTF-SpoonDog_PC.rar">download[/url]

 

I added the "debug" section to the .php script so I could see what was being set and make sure the variables look right and they do because when I hit the link it shows me this:

file is: CTF-SpoonDog_PC.rar
file_real is: http://www.themeinerz.com/dl_files/ut3/maps/pc/CTF-SpoonDog_PC.rar
POST:Array ( ) GET:Array ( [file] => CTF-SpoonDog_PC.rar ) Requested file does not exist

 

If I do a copy paste of the real_file value into a new browser tab it see's the file just fine...so what the heck is the deal here (why does it say the file doesn't exist)....any help would be greatly appreciated.

Link to comment
Share on other sites

The pages that will have the links to download the files are on a different server than the files themselves that was why I thought I had to give it the full http address. 

 

So the file is at http://www.themeinerz.com/dl_files/ut3/maps/pc/CTF-SpoonDog_PC.rar

 

The page that will link to that file is http://www.iamgaming.com/dev/dltest/

 

The reason I'm doing this is because I have unlimited bandwidth on one server and not on the other...

 

 

My main goal here is just to prevent people from seeing the path and posting direct download links to the file/s on sites other than mine.

Link to comment
Share on other sites

Hi WOPR,

 

I use this to get files off my local server to prevent full path disclosure but I have no idea if you can retrive files over http.

 

<?php
$filename = "CTF-SpoonDog_PC.rar";
$realfile = "http://www.themeinerz.com/dl_files/ut3/maps/pc/CTF-SpoonDog_PC.rar";

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename("filename"));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
readfile($realfile);
?>

 

May be worth a try.

Link to comment
Share on other sites

The reason I'm doing this is because I have unlimited bandwidth on one server and not on the other...

 

In order to "read()" a file it has to be, well, read. That means the server calling the file is reading it from the external server and then serving it to the user. You are, in effect, trippling your overall bandwidth and doubling it on the server where you have limited bandwidth:

 

Example:

 

User requests 10MB file from server 1

Server 1 reads file from server 2

- Server 1 uses 10MB in bandwidth from download

- Server 2 uses 10MB in bandwidth from upload

Server 1 then serves the file to the user

- Server 1 uses 10MB in bandwidth from upload

 

So, that 10MB file just cost you 30MB of bandwidth overall and 20MB is on server 1 (where you have limited bandwidth).

Link to comment
Share on other sites

The reason I'm doing this is because I have unlimited bandwidth on one server and not on the other...

 

In order to "read()" a file it has to be, well, read. That means the server calling the file is reading it from the external server and then serving it to the user. You are, in effect, trippling your overall bandwidth and doubling it on the server where you have limited bandwidth:

 

Example:

 

User requests 10MB file from server 1

Server 1 reads file from server 2

- Server 1 uses 10MB in bandwidth from download

- Server 2 uses 10MB in bandwidth from upload

Server 1 then serves the file to the user

- Server 1 uses 10MB in bandwidth from upload

 

So, that 10MB file just cost you 30MB of bandwidth overall and 20MB is on server 1 (where you have limited bandwidth).

 

Wow that is an excellent point that never even crossed my mind...So let me ask you this....does that scenario still apply if the download.php file was on server2 and I linked to it from server1?  Then everything comes from server2 even though you initiate it from a link on a page hosted by server1...right?

Link to comment
Share on other sites

Wow that is an excellent point that never even crossed my mind...So let me ask you this....does that scenario still apply if the download.php file was on server2 and I linked to it from server1?  Then everything comes from server2 even though you initiate it from a link on a page hosted by server1...right?

 

If I am understanding you correctly, that should work. You might even be able to do a header redirect from server 1 to server 2 to sort of mask it from the user, but I wouldn't guarantee that without validating it.

 

Example:

 

Script on server 1 for downloading files

if (isset($_GET['file_id']))
{
    header("Location: http://www.server2.com/downloadFile.php?file_id={$_GET['file_id']}");
}

 

Then just create the requisite script on server 2

Link to comment
Share on other sites

yep yep got it.  I will make sure to confirm that this works by watching my bandwidth but it makes sense to me.

 

Thanks a lot for the help! ;)

 

@ d_barszczak thanks for posting your code, that helped me clean up the script I was using.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.