Как я могу позволить пользователю загружать файл, который хранится вне webroot? - PullRequest
7 голосов
/ 03 декабря 2010

Я разрабатываю систему, которая позволяет зарегистрированным пользователям (которые могут быть кем угодно) загружать файлы. Я блокирую mime-типы и т. Д., Чтобы попытаться ограничить файлы типами .doc, .docx и .pdf, но для дополнительной безопасности они загружаются в папку вне webroot.

Другие пользователи могут затем выбрать загрузку файлов. Как я могу позволить им это сделать? Очевидно, я не могу просто вставить ссылку на файл, так как он находится за пределами руткита. Я не уверен, как добраться до файла, хотя! Я предполагаю, что могу использовать функции php-файла, чтобы добраться до файла, но как мне тогда «подать его» пользователю, который его запросил?

Какие последствия для безопасности могут иметь все это?

Спасибо.

Ответы [ 4 ]

10 голосов
/ 03 декабря 2010

Вам нужен PHP-скрипт, который выполняет следующие действия:

  1. Правильно установите заголовок типа контента (в зависимости от того, что загружает пользователь)
  2. Установите заголовок длины контентаправильно (в зависимости от размера файла)
  3. Открыть файл для чтения (вы можете использовать fopen)
  4. Считать файл и вывести его содержимое в выходной поток
  5. Готово

Вы также можете использовать функцию readfile , чтобы сделать то же самое.Вот пример с сайта PHP:

<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}
?>
0 голосов
/ 03 декабря 2010

Попробуйте следующее:

$fileName = basename($_GET['file']);
$path = 'path/to/data/'.$fileName;

// define $mimeType and $isAuthenticated

if ($isAuthenticated && file_exists($path)) {
    // serve file
    header('Content-type: '.$mimeType);
    header('Content-Disposition: attachment; filename="'.$fileName.'"');
    readfile($path);
} else {
    // 404
}

Вероятно, для этого потребуются дополнительные заголовки, но вы должны понять, как это можно использовать.

0 голосов
/ 03 декабря 2010

Вы можете поместить каталог с файлами в корневой каталог и применить правила перезаписи модов для обеспечения безопасности и отображения виртуального пути для пользователей вместо реального пути.

0 голосов
/ 03 декабря 2010

См. Ответы на этот похожий вопрос: Обратитесь к файлу за пределами дерева веб-сайта для целей загрузки , который ссылается на страницу руководства по PHP header *

...