Welcome to WebmasterWorld Guest from 54.204.100.232

Forum Moderators: coopster & jatar k

Message Too Old, No Replies

PHP hide url of file

   
7:55 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



How would I hide the URL of a file from a database, like http://www.example.com/files/?id=56 instead of http://www.example.com/files/lolwhut.zip

Or something similar, that doesn't show the folder, so people cant like hotlink them to other people?

7:58 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In your script you need to internally locate where file is and then read it and send back like this:

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"lolwhut.zip\"");

This way the end user will be prompted to open lolwhut.zip or save it, but they won't be actually getting it from location that can be secret.

8:51 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



so would I do header("Location: http://www.example.com/lolwhut.zip"); to locate it? Or how would I "internally locate" it?
8:55 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Nope: you do headers as I shown above, the filename should be without path - this would be the name that users browser will prompt to save or open.

What your script should do is fopen file internall and read from it while echoing back this information that will be sent to browser. This way you will send file's contents back to the user without giving away where the file is actually kept (it can be in database).

9:04 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ok this is confusing me, so I do fopen = "lolwhut.zip" or the directory that its in? And also how do I make it liek show up in a link, do I just stick this whole script between <a href="script">asda</a> tags or what?
9:04 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ok this is confusing me, so I do fopen = "lolwhut.zip" or the directory that its in? And also how do I make it liek show up in a link, do I just stick this whole script between <a href="script">asda</a> tags or what?
9:08 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ohh I think I got it. Well Im just adding $file = $_GET['file']; and readfile($file); then, I just do http://www.example.com/download/download.php?file=lolwhut.rar and it works. Is that a safe way of doing it? It opens the "Opening lolwhut.rar" as the title, then open with or save to disk thing.
9:09 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You need to have some kind of internal mapping that would allow you to locate actual filename from id=56 (as you gave in example above), this could be database table that will keep exact filename with unique id.

Once you know the filename you can open it using fopen and read and write back to client.

Run search on G for "fread php" and read carefully first entry - everything is explained there: the key trick in this case is internal mapping of id=65 to actual filename then using headers as I described above to avoid telling full path to the file.

9:13 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, you can't just read full filename as supplied in query string - this is a security risk and you will give away location of the file, what you need to do (if you don't want to use IDs as you initially asked) is check that no path was given in parameter (only filename), and then read file from some secret to the world directory - the end user will be only given filename, not full path where it is located, so they won't be able to get the file directly - just what you wanted.
9:15 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ok right now the URL that I'm doing is:

http://www.example.com/download/download.php?file=<?php echo $file; ?>

Its getting the url, and the download.php file is the page with the script on it. So that wouldn't be safe?

[edited by: eelixduppy at 9:20 pm (utc) on Feb. 20, 2008]
[edit reason] change to example.com [/edit]

9:18 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, it's not safe if you allow end users to specify path and filename they want to get without any validation - for example this may allow them to specify the download.php script itself to receive source code of it, surely that's not what you want? Anyway, I think I described it all above in detail - go to PHP site for fread function - good examples there.
9:25 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ok yeh I found this on that page from someone. Its working out so far, idk can you tell me if it would be safe? Because so far the script is working:

<?php
// Usage: <a href="download.php?file=test.txt&category=test">Download</a>
// Path to downloadable files (will not be revealed to users so they will never know your file's real address)
$hiddenPath = "secretfiles/";

// 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']) == 'download3.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){
// Display hack attempt error
echo("Hack attempt detected!");
die();
}
// 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 "asf": $type = "video/x-ms-asf"; break;
case "avi": $type = "video/x-msvideo"; break;
case "exe": $type = "application/octet-stream"; break;
case "mov": $type = "video/quicktime"; break;
case "mp3": $type = "audio/mpeg"; break;
case "mpg": $type = "video/mpeg"; break;
case "mpeg": $type = "video/mpeg"; break;
case "rar": $type = "encoding/x-compress"; break;
case "txt": $type = "text/plain"; break;
case "wav": $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 [0]
$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*8));
flush();
}
fclose($stream);
}
}else{
// Requested file does not exist (File not found)
echo("Requested file does not exist");
die();
}
}
}
?>

9:57 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yep, looks like this script checks for hacking attempt :)
10:03 pm on Feb 20, 2008 (gmt 0)

5+ Year Member



Ok yeh I'm having problems with it. I get this error when I click on the link:

Parse error: syntax error, unexpected T_STRING in /home/bfplanet/public_html/download/download.php on line 19

This is line 19:

if (substr($file, 0, 1) == '.' strpos($file, '..') > 0 substr($file, 0, 1) == '/' strpos($file, '/') > 0){

Any ideas?

10:06 pm on Feb 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Sorry, too tired for that - you will need to look carefully at syntax of code in a good highlighting editor, check manual of PHP how it should be etc - I can't do everything for you, I merely posted to give you key hint how to achieve what you want, you will have to work out details for yourself, sorry...