Как обслуживать документы из-за пределов веб-корня с помощью PHP?

#php

#php

Вопрос:

Для обеспечения безопасности я перемещаю коллекцию файлов и папок за пределы веб-корня на сервере apache, а затем я буду обслуживать их динамически. Это кажется лучше, чем 2 альтернативы:

  1. Оставьте их доступными в Интернете и просто создайте страницу входа в php, которая добавляется к каждому файлу. Проблема в том, что это не все файлы php, и я не могу добавить файл входа php в pdf, изображение и т. Д.
  2. Оставьте их доступными для Интернета и используйте HTTP-аутентификацию, чтобы ограничить доступ ко всему каталогу. Но это создает проблемы, включая пароли с открытым текстом, отсутствие изящного метода выхода из системы и т. Д.

Итак, мы вернулись к тому, что они находятся за пределами веб-корня, но обслуживаем их динамически. Проблема, с которой я сталкиваюсь, заключается в том, что все они имеют разные типы файлов (php-скрипты, txt, pdf, jpg) Я не уверен, следует ли мне использовать include() или readfile() . И у меня возникают проблемы с отправкой правильных заголовков для каждого файла, чтобы браузер отображал их правильно.

Я упускаю еще одно волшебное решение? Существует ли ускользнувшая от меня структура, которая обрабатывает обслуживание динамических файлов и заголовков?

(К вашему сведению, я использую Linux, Apache и PHP на общем хосте)

Комментарии:

1. Вау, вы берете легкую проблему и превращаете ее в сложную.

2. @Dietrich какое тогда было бы простое решение?

3. @Pekka: HTTP-дайджест-аутентификация, попросите пользователей закрыть свои браузеры для выхода из системы.

4. @Dietrich чаще всего это не вариант, если у вас есть расширенное управление пользователями и аутентификация. Я согласен, что это печальное положение дел, и передача файлов через PHP-скрипт — ужасная трата ресурсов, но на самом деле нет простого решения

5. @Pekka: Вопрос намекает на то, что это вариант. И передача файлов через PHP-скрипт — это не настоящая трата ресурсов. Настоящая трата ресурсов — это написание и отладка скрипта, который никогда не нужно было писать в первую очередь.

Ответ №1:

Я думаю, что что-то вроде этого сработало бы:

 <?php
$path = realpath(dirname(__FILE__) . '/../my_files/' . $_GET['file']);

$parts = explode('/', pathinfo($path, PATHINFO_DIRNAME));
if (end($parts) !== 'my_files') {
    // LFI attempt
    exit();
}

if (!is_file($path)) {
    // file does not exist
    exit();
}

header('Content-Type: ' . mime_content_type($path));
header('Content-Length: ' . filesize($path));

readfile($path);
  

Комментарии:

1. Я бы mime_content_type() заменил функции fileinfo, но в остальном да.

Ответ №2:

Самый простой способ, который я могу придумать, — это использовать файлы .htaccess. Предполагая, что ваш веб-сервер Apache, конечно.

Вы можете запретить доступ к любым типам файлов и / или каталогов для всех и разрешить только для localhost. Таким образом, они не будут доступны для общественности, даже если они знают правильный путь / url, но сервер и PHP смогут их обслуживать.

Для разных веб-серверов должны быть эквивалентные решения. Кроме того, вы всегда можете переключиться на Apache 🙂

Комментарии:

1. Ну, сокрытие файлов от общественности не было проблемой. Перемещение их за пределы веб-корня или ограничение доступа с помощью .htaccess эквивалентны мне. Моя проблема — хороший метод выборочного обслуживания этих файлов, когда это необходимо, авторизованным пользователям.

2. … и, вероятно, без использования простой http-аутентификации. В противном случае .htaccess все равно будет вариантом.

3. Эти две проблемы независимы… Но поскольку вы взяли абзац, чтобы объяснить свой выбор перемещения их из веб-корня, я подумал, что хотел бы указать, что это не является необходимым шагом. А именно, когда вы говорите «… для безопасности я перемещаю …», это не точная причина или мера.

4. Правильно. Понятно. Я ценю вклад.