Есть скрипт-читалка: http://site.com/class/download.php?filename=[/path/to/file]%00.pdf
Внутри такой волшебный код (см. ниже).
Используются блэк- и вайт-листы, фильтрация расширения на удивление обходится нулл-байтом, но есть проблемы с путями. Надо прочитать файл из ../config/, какие варианты?
PHP код:
/*
This function will prompt user for downloading file.
*/
function downloadFile() {
// validation
if($this->strFileDownload != "" && $this->strFileName != "") {
// here just check whether they exist or not and if exist download it
if(file_exists($this->strFileDownload)) {
header("Cache-Control: private");
header("Content-type: " . filetype($this->strFileDownload) . "");
header("Content-Disposition: attachment; filename=\"" . $this->strFileName . "\";");
header("Accept-Ranges: bytes");
header("Content-Length: " . filesize($this->strFileDownload) . "");
@readfile($this->strFileDownload);
}
else{
print("File does not exist.");
}
}
else{
print("File name is blank.");
}
}
/*
This function is used to check requested downloading whether it is valid or not. if not valid then redirect to home page of the site.
*/
function checkValidDownloading() {
if(DEBUG) print("checkValidDownloading()<br/>");
// initialing array for folders and files extensions
$this->arrNotAllowedFolders = array(
'0' => "/adimages/",
'1' => "/admin/",
'2' => "/backups/",
'3' => "/class/",
'4' => "/config/",
'5' => "/css/",
'6' => "/db/",
'7' => "/designs/",
'8' => "/fixes/",
'9' => "/fonts/",
'10' => "/temp/",
'11' => "/helpdocs/",
'12' => "/holdingpage/",
'13' => "/images/",
'14' => "/js/",
'15' => "/logs/",
'16' => "/modules/",
'17' => "/scripts/"
);
$this->arrAllowedFiles = array(
'0' => ".csv",
'1' => ".tsv",
'2' => ".txt",
'3' => ".pdf",
'4' => ".xml",
'5' => ".doc",
'6' => ".docx",
'7' => ".html",
'8' => ".xls",
'9' => ".jpg",
'10' => ".jpeg",
'11' => ".gif",
'12' => ".png",
'13' => ".bmp",
'14' => ".htm"
);
// set REQUEST URI and requested file's extension, flagExit
if(isset($_REQUEST['fileName']) && !empty($_REQUEST['fileName'])) {
$strReqUri = $_REQUEST['fileName'];
$strFileExt = substr($strReqUri, strrpos($strReqUri, '.'));
$flagExit = false;
// check for from which folder request comes, if folder exists in out NotAllowed list then redirect to home page
foreach($this->arrNotAllowedFolders as $key => $strFolder) {
if(strpos($strReqUri, $strFolder) !== false) {
$flagExit = true;
break;
}
}
// if requested folder valid then check for file extension
if(!$flagExit) {
if(!in_array($strFileExt, $this->arrAllowedFiles)) {
$flagExit = true;
}
}
// redirect to home page if flagExit set TRUE
if($flagExit) {
// redirect to home page
$back = ABSPATH;
if(DEBUG) {
print("<a href=\"" . $back . "\">Back</a><br/>");
}
else {
header("Location: " . $back);
}
exit();
}
}
else {
// redirect to home page
$back = ABSPATH;
if(DEBUG) {
print("<a href=\"" . $back . "\">Back</a><br/>");
}
else {
header("Location: " . $back);
}
exit();
}
}