Ограничить доступ к файлам - только чтение через PHP [закрыто]

Я использую план веб-хостинга GoDaddy на платформе Windows. Это был не мой выбор - это связано с другой частью фактического сайта, используя ASP.NET (тоже не мой выбор).

У меня есть база данных SQL с кучей записей с некоторой нечувствительной информацией о клиентах. Первичный ключ на этом является целым числом автоинкремента, и у меня есть ряд PDF-файлов, которые соответствуют каждому из этих целых чисел (например, 555.формат PDF, 7891.PDF и т. д.).

моя цель-ограничить прямой доступ к этим файлам, я хочу, чтобы пользователи должны пройти через процесс поиска и входа в систему (PHP) в первую очередь. Первоначально я планировал поместить файлы выше папки PUBLIC_HTML, но GoDaddy отказывается предоставить мне корневой доступ без выделенного сервера ($20 в месяц от них).

следующее, что я посмотрел, был HTACCESS. Я собирался ограничить доступ к файлам только PHP-скриптами, разрешив доступ только к IP-адресу сервера (или localhost/127.0.0.1). К сожалению, это не работа, потому что GoDaddy не запускает Apache на своих серверах Windows.

Я мог бы поместить файлы в BLOBs в базе данных, но это становится очень грязным, когда мне нужно работать с ними быстро (плюс у меня были некоторые проблемы с этим подходом).

любые предложения по ограничению доступа к файлам только скриптом PHP (readfile ())?

4 ответов


поскольку вы не можете поместить файлы в любом месте, кроме каталога public_html, вам придется пойти на метод "безопасность по неизвестности"

  1. создайте случайно названный подкаталог для хранения файлов в: public_html / RANDOMGARBAGE

  2. убедитесь, что каталог не доступен для просмотра. Отключите просмотр каталогов (если можете) и поместите документ по умолчанию (index.HTML-код?) там также, Так что даже если просмотр включен, вы не получите список каталогов.

  3. не храните файлы с угадываемыми именами. Вместо того, чтобы хранить их с идентификатором базы данных, храните их с соленым+хэшированным именем вместо: $crypted_filename = sha1($real_filename . 'some hard-to-guess salt text'); (конечно, сделать это более сложным, если вам нужно). Сохранить исходное имя файла в базе данных. Так что вы в конечном итоге с чем-то вроде:

    public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8

  4. подавать файлы через php-скрипт-никогда не ссылаться на хэшированное имя файла прямо

    скачать

что потом:

<?php

    $fileID = (int)$_GET['fileID'];

    $crypted_file = sha1($fileID . 'some hard-to-guess salt text');

    $full_path = 'public_html/RANDOMGARBAGE/' . $crypted_file;
    if (is_readable($full_path)) {
         if(user_is_allowed_to_see_this_file()) {
             /// send file to user with readfile()
             header("Content-disposition: attachment; filename=$ORIGINAL_FILENAME");
             readfile($full_path);
         } else {
             die("Permission denied");
         }
    } else {
        /// handle problems here
        die("Uh-oh. Can't find/read file");
    }

таким образом, пользователь никогда не увидит, что ваше имя файла "s00per seekrit", они просто увидят, что их браузер попал ...php?fileID=37 и начать загрузку secret file.pdf

кроме того, вы можете иногда переименовывать специальный подкаталог в что-то еще на регулярной основе, а также изменять текст соли (который затем требует обновления всех хэшированных имен файлов с новым sha1 значения.)


поскольку PHP использует разрешения пользователя веб-сервера, невозможно ограничить доступ к файлам без:

  • размещение их вне DOCROOT
  • изменение конфигурации веб-сервера, чтобы запретить доступ к этим файлам
  • изменение файла, чтобы он был интерпретирован веб-сервером, скрывая его содержимое

размещение их в базе данных считается за пределами DOCROOT. Для третьего варианта, вы могли бы сделать файлы PHP PDFs, но, честно говоря, это было бы довольно запутанно.

Я рекомендую вам связаться с GoDaddy и посмотреть, есть ли у них какой-то способ настроить права доступа к файлам в каталоге.


Вы можете просто скрыть их. Это безопасность через неизвестность, но это звучит как ваш лучший вариант, если вы не можете либо держать их вне веб-корня, либо найти способ сказать серверу не обслуживать их напрямую.

поэтому вставьте их в какой-то случайно названный каталог:

asd8b8asd8327bh/123.pdf
asd8b8asd8327bh/124.pdf
asd8b8asd8327bh/125.pdf
...

затем напишите себе небольшой PHP-скрипт, который отправит соответствующие заголовки и передаст содержимое файла.

например:

<?PHP
//pdf.php
$id = $_GET['id'];

//make sure nobody is doing anything sneaky. is_numeric() might do the trick if the IDs are always integers.
if (!some_validation_passes($id)){
  die();
}
<?php

header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="'.$id.'.pdf"');
readfile('asd8b8asd8327bh'.$id.'pdf');

теперь выше на самом деле не лучше, чем просто обслуживать файлы напрямую (пока), так как люди все еще могут увеличивать параметр id в строке запроса.

но вы должны быть в состоянии выяснить, как обрабатывать авторизацию довольно легко.


сделать веб-папку недоступной через chmod. PHP по-прежнему сможет включать/требовать все, что находится на сервере, но пользователи не смогут перейти к файлам когда-либо.

пример: Это установлено в 770, т. е. пользователь и группа могут читать/писать / выполнять, другие ничего не могут сделать.