Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - How to set full directory path in Content-Disposition?

I am passing a filename to a download page.
ie somefile.xls

The download page adds back in the full directory path onto the filename.
ie c:\temp\somefile.xls

The problem is that now setting the 'Content-Disposition' of the header doesn't work. The filename it wants to download is the full directory-filename path. ie c_temp_somefile

Can the Content-Disposition handle a full path?

If it can how do I get my script to properly download the file?

Code is:

$myad = $_GET['myad'];
$glob_string =  realpath('/foldera/folderb/folderc'). DIRECTORY_SEPARATOR .$myad;

header('Content-Type: application/excel');
$headerstring = 'Content-Disposition: attachment; filename='.$glob_string;
header($headerstring);
readfile($myad);

UPDATED code (from answers):

$myad = $_GET['myad'];
$glob_string =  realpath('/mit/mit_tm/mrl_bol'). DIRECTORY_SEPARATOR .$myad;

header('Content-Type: application/excel');
$headerstring = 'Content-Disposition: attachment; filename='.$myad;
header($headerstring);
readfile($glob_string);    
like image 975
John M Avatar asked Nov 18 '09 17:11

John M


People also ask

What is httpheaders Content_ Disposition?

In a regular HTTP response, the Content-Disposition response header is a header indicating if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.

What is Content Disposition attachment filename?

Content-Disposition is an optional header and allows the sender to indicate a default archival disposition; a filename. The optional "filename" parameter provides for this. This header field definition is based almost verbatim on Experimental RFC 1806 by R. Troost and S.

What is Content Disposition inline?

1. Content Disposition Type : inline: This indicates that data should be displayed automatically on prompt in browser. attachment: This indicates that user should receive a prompt (usually a Save As dialog box) to save the file locally on the disk to access it.

What is Content Disposition in java?

The MIME Content-disposition header provides presentation information for the body-part. It is often added to attachments specifying whether the attachment body part should be displayed (inline) or presented as a file name to be copied (attachment).


1 Answers

Don't pass the full path via the header string, but use the base name ($myad) instead.

You should really use a better validation for $_GET['myad'], since your script will pass arbitrary paths to the user (readfile() gets the unfiltered user input). This is a security hole!

Calculate the real path using realpath, make sure that the file is within a allowed folder, then use basename() on the full path to get the plain file name. Pass this substring via the Content-Disposition header, but use the real path for readfile().


UPDATE: Your updated code still contains a security hole. If $_GET['myad'] contained ../../../some/full/path, your script would happily send any requested readable file to the client.

You should use something along the lines of the following snippet:

$myad = $_GET['myad'];

$rootDir = realpath('/mit/mit_tm/mrl_bol');
$fullPath = realpath($rootDir . '/' . $myad);

// Note that, on UNIX systems, realpath() will return false if a path
// does not exist, but an absolute non-existing path on Windows.
if ($fullPath && is_readable($fullPath) && dirname($fullPath) === $rootDir) {
    // OK, the requested file exists and is in the allowed root directory.
    header('Content-Type: application/excel');
    // basename() returns just the file name.
    header('Content-Disposition: attachment; filename=' . basename($fullPath));
    readfile($fullPath);
}
like image 158
Ferdinand Beyer Avatar answered Nov 03 '22 04:11

Ferdinand Beyer