Md5sums wrong on downloaded files

I thought I had this problem solved, but it isn’t. Still having a problem with downloaded files having the wrong md5sum. I’ve scrubbed the script again to be sure there aren’t any tabs or blank spaces following the commands. Also no php errors. Here’s the code.

<?PHP
error_reporting(E_ALL);
ini_set('display_errors', '1');

function mydloader($filename=NULL) {
    if (isset($filename)) {
        $filename = preg_replace("/\s+/u", " ", $filename);  // Make sure no hidden characters in filename
        $ext = pathinfo($filename, PATHINFO_EXTENSION);{  // Get file extension
        if ($ext == '.iso')
            header('Content-Type: application/x-cd-image');
        elseif ($ext == '.gz')
            header('Content-Type: application/zip');
        else
            header('Content-Type: octet-stream');}
            header("Content-Disposition: attachment; filename={$filename}");
            header('Pragma: no-cache');
            header('Expires: 0');
            readfile($filename);
}
       else {
          echo "isset failed";
            }
}
mydloader($_GET["f"]);  // Filename passed from calling script

I’m totally confused as to why this isn’t working correctly. I spent the entire weekend trying go get this working so I’d really appreciate some help on this.

Here’s and example of the differences:

md5sum of original file: a00bd61088cf4f4a0138d51f24e554f0

md5sum of downloaded file: 6f23af927c0a3348345ed1415fb89e36

Seeing the actual hash values doesn’t help, other than to see that they are different.

What is the filesize of the original and the downloaded file? If downloaded file is much smaller than the original, it means that something is truncating the download. If the downloaded file is slightly larger than the original, it means that something is being added to it during the download.

For the later case, I would use a hex file viewer/editor to examine the start and end of both of the files to see what is different between them - Comparison of hex editors - Wikipedia

@phdr - They are different in the hex editors.

Original file shows: Signed 32 bit as: 1769108595

Downloaded file shows: Signed 32 bit as: 1751347809

Sizes:
original size: 5674712
download size: 5674783

I also xxd’d both files and compared them in Meld. It appears that the filename is being pre-pended to the downloaded file.

Question for you: could that preg_replace() in the code be causing this issue?

That’s actually the output from a var_dump of $filename being prepended.

What is the date/time of this downloaded file? I suspect it is left over from some previous testing or that this is occurring on your localhost development system, where the php code may not be the same as what you have posted.

Only if you have multiple files, some with white-space character(s) (spaces, tab(s), newline(s)) in them and some with only single spaces in them, so that the preg_replace causes a requested filename to be altered to match a version of the name with only single spaces in it. Also, the resulting downloaded filename would be the one with the single spaces in it.

Related to using the requested file name in this download code. You were previously told to NOT blindly accept and use a filename as it will allow any file on your server to be downloaded. Your database connection and php.ini files can be easily downloaded (I recommend that you remove this code from the live site and change your connection password asap.) Also, on your live server you can browse the various folders. Assuming this is an apache web server, you need to add the following to the .htaccess file, to prevent browsing of folders that don’t have a default index file -

Options -Indexes

As to the current and full mydloader.php code. You cannot use a url for the require statement as that will make a separate http(s) request to your own server for those files. They will be executed in a separate instance of your web server and won’t have access to the current context of your code. This is also appending a bunch of php errors to the end of the downloaded files, since the setting needed to make a url require work is turned off.

Will update the .htaccess file.

I’m having problems connecting to the database, that’s why I had the path using the full url.
It was set to …/…/php. The download folder is directly under the public_html folder and the php folder is directly above the public_html folder, so that path should work.

I’ve never learned how to sanitize a filename. Can you provide an example?

I no longer have the downloaded file, so I can’t give you the date/time it was downloaded. If you want, I can download it again from the live system and do the analysis again and give you the results.

Thanks for your time and sharing your knowledge.

Sponsor our Newsletter | Privacy Policy | Terms of Service