Я использую план хостинга GoDaddy на платформе Windows. Это был не мой выбор – он имеет отношение к другой части фактического сайта, используя ASP.NET (также не мой выбор).
У меня есть база данных SQL с множеством записей с некоторой нечувствительной информацией о клиенте. Первичным ключом является целое число AutoIncrement, и у меня есть серия PDF-файлов, которые соответствуют каждому из этих целых чисел (например, 555.pdf, 7891.pdf и т. Д.).
Моя цель – ограничить прямой доступ к этим файлам, я хочу, чтобы пользователи сначала просматривали процесс поиска и входа в систему (PHP). Первоначально я планировал разместить файлы над папкой PUBLIC_HTML, но GoDaddy отказывается предоставить мне root-доступ без выделенного сервера (от $ 20 в месяц от них).
Следующее, что я рассмотрел, было HTACCESS. Я собирался ограничить доступ к файлам только сценариям PHP, только разрешив доступ к IP-адресу сервера (или localhost / 127.0.0.1). К сожалению, это не работает, потому что GoDaddy не запускает Apache на своих серверах Windows.
Я могу поместить файлы в BLOB в базе данных, но это становится очень грязным, когда мне нужно быстро работать с ними (плюс у меня были некоторые проблемы с этим подходом).
Любые предложения по ограничению доступа к файлам только для скрипта PHP (readfile ())?
Поскольку вы не можете поместить файлы в любом месте, но в свой каталог 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. Для третьего варианта вы можете сделать файлы PDF файлов PDF, но, честно говоря, это было бы довольно запутанным.
Я рекомендую вам обратиться в 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, пользователь и группа IE могут выполнять чтение / запись / выполнение, другое ничего не может сделать.