Reputation: 61
Hi i'm trying to download a file from the file "upload". I'm using thin cobe but the result is "I'm sorry, the file doesn't seem to exist"
here is my call
<a href="download.php?filename=<?php $row4['Arxeio'] ?>">Click here
to Download the File</a>
and download.php
<?php session_start();
$filename = $_GET['filename'];
$download_path = './upload/';
if(eregi("\.\.", $filename)) die("I'm sorry, you may not download that file.");
$file = str_replace("..", "", $filename);
// Make sure we can't download .ht control files. if(eregi("\.ht.+", $filename)) die("I'm sorry, you may not download that file.");
// Combine the download path and the filename to create the full path to the file. $file = '$download_path$filename';
// Test to ensure that the file exists.
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
// Extract the type of file which will be sent to the browser as a header
$type = filetype($file); // Get a date and timestamp $today = date("F j, Y, g:i a"); $time = time(); // Send file headers header("Content-type: $type"); header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0'); // Send the file contents.
set_time_limit(0);
readfile($file);
?>
Upvotes: 1
Views: 10649
Reputation: 270727
In your HTML, you need to echo
the filename for it to be written to output:
<a href='download.php?filename=<?php echo $row4['Arxeio']; ?>'>Click here to Download the File</a>
When receiving the filename in PHP, you must validate it against directory traversal attacks. Verify that it contains no /
or ..
. You have a rudimentary test with eregi()
(which is deprecated, by the way), but it can be done simply with strpos()
.
if (strpos($filename, "..") >= 0 || strpos($filename, "/") >= 0) {
// Error! don't permit file download
}
Review PHP's documentation on NULL byte attack protection as well.
Better though, would be to compare the $filename
against a whitelist of valid filenames for download:
if (in_array($filename, array('file1.jpg', 'file2.txt', 'file3.mov',...)) {
// Ok, send the file.
}
else {
// Invalid file
}
Upvotes: 3