0

I have the following file hierarchy :

  • downloader.php (to download the files only through the php page for logged in users and block direct access through .htaccess file )
  • 10-C-Language (a directory containing some pdf files )
  • C Language 2019 First + notes.pdf (a pdf file contained in "10-C-Language" directory)

The link sent to the downloader.php is as follows:

downloader.php?file=10-C-Language/C%20Language%202017%20First%20%20+%notes.pdf

but it returns

File does not exist.

although the file does exist !

here is the php code for the downloader:

<?php
include('session.php');
if (isset($_GET['file'])) {
    //Read the filename
    $filename = $_GET['file'];
    //Check the file exists or not
    $extension = pathinfo($filename, PATHINFO_EXTENSION);
    $allowed = array('pdf', 'txt', 'docx', 'rar', 'zip', 'jar');
    if (!in_array($extension, $allowed)) {
        echo 'You don't have permission to download this type of files.';
    } else {
        if (file_exists($filename)) {
            //Define header information
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header("Cache-Control: no-cache, must-revalidate");
            header("Expires: 0");
            header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
            header('Content-Length: ' . filesize($filename));
            header('Pragma: public');

            ob_clean();
            //Clear system output buffer
            flush();

            //Read the size of the file
            readfile($filename);

            //Terminate from the script
            die();
        } else {
            echo "File does not exist.";
        }
    }
} else
    echo "Filename is not defined."
?>

Some files are containing spaces ,but they are downloaded fine ,but for other cases like the ond described above it doesn't work !

So what is the problem here ?!

Regards

Colin Jack
  • 209
  • 3
  • 13
  • 7
    The file name is url encoded. So decode it. https://www.php.net/manual/en/function.urldecode – Markus Zeller Sep 02 '22 at 07:47
  • 4
    Both `%20` as `+` in urls are (different forms of) urlencoded spaces. You should probably actually encode the `+` to `%2B` in your client if it is not meant to be a space. – ontrack Sep 02 '22 at 07:48
  • Have you debugged to see what the actual value of `$filename` is when you receive it? – ADyson Sep 02 '22 at 07:49
  • 4
    BTW do you really want this script to be able to download absolutely any file from your filesystem? That's a big security risk, potentially, as it gives access to operating system files, and thus information about how the computer is configured. – ADyson Sep 02 '22 at 07:50
  • Also, please! read up on directory traversal bugs, dont just plainly use user-input to download a file. See for example https://stackoverflow.com/questions/4205141/preventing-directory-traversal-in-php-but-allowing-paths – ontrack Sep 02 '22 at 07:50
  • @ontrack and Markus Zeller , encoding the + to %2B did the trick thanks a lot – Colin Jack Sep 02 '22 at 14:15
  • 1
    @ADyson you made me realize how dangerous was this , so i did some checks on the downloader.php for the the file extension before allowing the download and it did work for protecting the php files from being downloaded , do you think this is the best approach ? or is there any better ideas ? please see the updated code above for the downloader . – Colin Jack Sep 02 '22 at 14:18
  • 1
    That looks a bit more sensible yes, have you tested it? You might want to think about restricting it to certain folders as well – ADyson Sep 02 '22 at 14:24
  • @ADyson Yes tested and works fine and doesn't allow to download other files format like .php this along with the .htaccess are good for now for protecting all the important files I need and I will take into consideration protecting the other folders as well , at last thanks a lot for the valuable comment above . – Colin Jack Sep 02 '22 at 14:38
  • 1
    Also, your echo has incorrect string quotes, e.g., `echo 'You're ...';` will not work. Either you use double quotes as `echo "You're ...";` or escape the second quote as `echo 'You\'re ...';`. In the future, for safety use double quotes for strings – samayo Sep 02 '22 at 14:46
  • @samayo ...unless you want to show double quotes in the output, of course! :-) – ADyson Sep 02 '22 at 14:49

0 Answers0