Ограничить доступ к файлам - только чтение через 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, вам придется пойти на метод "безопасность по неизвестности"
создайте случайно названный подкаталог для хранения файлов в: public_html / RANDOMGARBAGE
убедитесь, что каталог не доступен для просмотра. Отключите просмотр каталогов (если можете) и поместите документ по умолчанию (index.HTML-код?) там также, Так что даже если просмотр включен, вы не получите список каталогов.
-
не храните файлы с угадываемыми именами. Вместо того, чтобы хранить их с идентификатором базы данных, храните их с соленым+хэшированным именем вместо:
$crypted_filename = sha1($real_filename . 'some hard-to-guess salt text');
(конечно, сделать это более сложным, если вам нужно). Сохранить исходное имя файла в базе данных. Так что вы в конечном итоге с чем-то вроде:public_html/RANDOMGARBAGE/5bf1fd927dfb8679496a2e6cf00cbe50c1c87145
public_html/RANDOMGARBAGE/7ec1f0eb9119d48eb6a3176ca47380c6496304c8
-
подавать файлы через 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, т. е. пользователь и группа могут читать/писать / выполнять, другие ничего не могут сделать.