У меня есть php-файл, который я буду использовать исключительно как включаемый. Поэтому я хотел бы выдать ошибку вместо его выполнения, когда к нему обращаются напрямую, набирая его URL. То есть мне нужно сделать следующую проверку в php-файле:
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Прямой доступ к файлу запрещен");
Есть ли простой способ сделать это?
Ответ 1
Самый простой способ для стандартной ситуации «PHP-приложение работает на сервере Apache, который вы можете полностью или не полностью контролировать» – поместить ваши include в каталог и запретить доступ к этому каталогу в файле .htaccess. Чтобы избавить людей от необходимости гуглить, если вы используете Apache, поместите это в файл под названием ".htaccess" в директории, к которой вы не хотите иметь доступ:
Deny from all.
Если у вас действительно есть полный контроль над сервером (в наши дни это более распространено даже для небольших приложений), лучший подход – поместить файлы, которые вы хотите защитить, вне каталога, из которого обслуживается ваш веб-сервер. Так, если ваше приложение находится в /srv/YourApp/, установите сервер на обслуживание файлов из /srv/YourApp/app/ и поместите include в /srv/YourApp/includes, так чтобы не было никакого URL, который может получить к ним доступ.
Ответ 2
Добавьте это к странице, которую вы хотите, чтобы только она была включена:
<?php
if(!defined('MyConst')) {
die('Прямой доступ запрещен');
}
?>
затем на страницах, включающих его, добавьте:
<?php
define('MyConst', TRUE);
?>.
Ответ 3
1. Проверка количества включенных файлов
if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) ) {
exit('Ограниченный доступ');
}
Логика: PHP завершает работу, если не соблюдается минимальное количество включений. Обратите внимание, что до PHP5 базовая страница не считалась включаемой.
2: Определение и проверка глобальной константы
// На базовой странице (прямой доступ):
define('_DEFVAR', 1);
// В включаемых файлах (где прямой доступ запрещен):
defined('_DEFVAR') or exit('Ограниченный доступ');
Логика: если константа не определена, то выполнение не началось с базовой страницы, и PHP перестанет выполняться.
Обратите внимание, что для обеспечения переносимости между обновлениями и будущими изменениями создание модульного метода аутентификации значительно сократит накладные расходы на кодирование, поскольку изменения не нужно будет жестко запрограммировать для каждого отдельного файла.
// Поместите код в отдельный файл, например, 'checkdefined.php':
defined('_DEFVAR') or exit('Ограниченный доступ');
// Замените тот же код в включаемых файлах на:
require_once('checkdefined.php');
Таким образом, можно добавить дополнительный код checkdefined.php для ведения журнала и аналитических целей, а также для генерации соответствующих ответов.
3: Авторизация удаленного адреса
// Вызовите include из базовой страницы (прямой доступ):
$includeData = file_get_contents("http://127.0.0.1/component.php?auth=token");
// В включаемых файлах (где прямой доступ запрещен):
$src = $_SERVER['REMOTE_ADDR']; // Получение исходного адреса
$auth = authoriseIP($src); // Алгоритм авторизации
if( !$auth ) exit('Ограниченный доступ');
Недостатком этого метода является изолированное выполнение, если только токен сеанса не предоставлен с внутренним запросом. Подтвердите с помощью обратного адреса в случае конфигурации с одним сервером или белого списка адресов для многосерверной или серверной инфраструктуры с балансировкой нагрузки.
4: Авторизация токена
Как и в предыдущем методе, можно использовать GET или POST для передачи токена авторизации в включаемый файл:
if($key!="serv97602"){header("Location: ".$dart);exit();}
Очень запутанный метод, но, возможно, в то же время самый безопасный и универсальный при правильном использовании.
5: Конфигурация конкретного веб-сервера
Большинство серверов позволяют назначать разрешения для отдельных файлов или каталогов. Вы можете поместить все свои включения в такие ограниченные каталоги и настроить сервер на их запрет.
Например, в APACHE конфигурация хранится в файле .htaccess.
Однако обратите внимание, что конфигурации для конкретных серверов я не рекомендую, потому что они плохо переносятся на разные веб-серверы. В таких случаях, как системы управления контентом, где алгоритм запрета является сложным или список запрещенных каталогов довольно велик, это может только сделать сеансы реконфигурации довольно запутанными.
6. Размещение включает в себя безопасный каталог ВНЕ корня сайта.
Наименее предпочтительный из-за ограничений доступа в серверных средах, но довольно мощный метод – если у вас есть доступ к файловой системе.
//Ваш безопасный путь к каталогу, основанный на файловой системе сервера
$secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR;
include($secure_dir."securepage.php");
Логика:
Пользователь не может запросить какой-либо файл за пределами папки htdocs, поскольку ссылки будут выходить за рамки адресной системы веб-сайта.
Сервер php обращается к файловой системе изначально и, следовательно, может получать доступ к файлам на компьютере так же, как это может делать обычная программа с необходимыми привилегиями.
Поместив включаемые файлы в этот каталог, вы можете гарантировать, что php-сервер получит к ним доступ, в то время как горячие ссылки запрещены для пользователя.
Даже если конфигурация доступа к файловой системе веб-сервера не была выполнена должным образом, этот метод предотвратит случайное открытие доступа к этим файлам.
Ответ 4
Мой ответ несколько отличается по подходу, но включает в себя многие из представленных здесь ответов. Я бы порекомендовал разносторонний подход:
.htaccess и ограничения Apache
defined('_SOMECONSTANT') or die('Хакеры! Уходите!');
ОДНАКО этот defined or die подход имеет ряд недостатков. Во-первых, это настоящая боль в предположениях, которые нужно тестировать и отлаживать. Во-вторых, это включает запутанный, утомительно скучный рефакторинг, если вы передумаете.
А еще есть .htaccess. Что будет, если ваш код будет распространен на сайтах, где администратор не столь щепетилен? Если вы полагаетесь только на .htaccess для защиты своих файлов, вам также понадобится а) резервная копия, б) много времени на поиски всех уязвимостей. Итак, я знаю, что вопрос требует «самого простого решения», но я думаю, что это требует более «защитного кодирования».
Я предлагаю:
Перед любым из ваших скриптов использовать require('ifyoulieyougonnadie.php');( не include() и в качестве замены defined or die)
В ifyoulieyougonnadie.php, сделайте некоторые логические вещи - проверьте различные константы, вызывающий скрипт, тестирование localhost и т. д. - а затем реализуйте свой die(), throw new Exception, 403и т. д.
Я создаю свой собственный фреймворк с двумя возможными точками входа – основной index.php (фреймворк Joomla) и ajaxrouter.php (мой фреймворк), поэтому в зависимости от точки входа я проверяю разные вещи. Если запрос ifyoulieyougonnadie.phpне исходит от одного из этих двух файлов, я знаю, что осуществляется взлом!
Но что, если я добавлю новую точку входа? Без проблем. Я просто меняю ifyoulieyougonnadie.php и сортирую его, плюс никаких «найти и заменить».
Что, если бы я решил переместить некоторые из моих скриптов в другую структуру, в которой нет таких же констант defined()? ...
Я обнаружил, что эта стратегия делает разработку намного интереснее и намного проще:
// defined('_JEXEC') or die();
class perfectlyWorkingCode {}
perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();
Ответ 5
Помимо способа .htaccess, я видел полезный паттерн в различных фреймворках, например, в ruby on rails. У них есть отдельный каталог pub/ в корневом каталоге приложения, а каталоги библиотек находятся в каталогах того же уровня, что и pub/. Что-то вроде этого:
app/
|
+--pub/
|
+--lib/
|
+--conf/
|
+--models/
|
+--views/
|
+--controllers/.
Вы настраиваете свой веб-сервер на использование pub/ в качестве корня документа. Это обеспечивает лучшую защиту ваших скриптов: хотя они могут обращаться к корню документа для загрузки необходимых компонентов, получить доступ к ним из Интернета невозможно. Еще одним преимуществом, помимо безопасности, является то, что все находится в одном месте. Такая настройка лучше, чем просто создание проверок в каждом отдельном включенном файле, потому что сообщение "доступ запрещен" является подсказкой для злоумышленников, и лучше, чем настройка .htaccess, потому что она не основана на белых списках: если вы испортите расширения файлов, это не будет видно в каталогах lib/, conf/ и т.д.
Ответ 6
О хранении включаемых файлов вне веб-доступного каталога уже упоминалось несколько раз, и это, конечно, хорошая стратегия, если она возможна. Однако я еще не видел упоминания о другом варианте: убедитесь, что ваши включаемые файлы не содержат запускаемого кода. Если ваши включаемые файлы просто определяют функции и классы и не содержат никакого другого кода, то при прямом доступе к ним будет просто выдаваться пустая страница.
Всеми средствами разрешите прямой доступ к этому файлу из браузера: он ничего не сделает. В нем определены некоторые функции, но ни одна из них не вызывается, поэтому ни одна из них не выполнится.
<?php
function a() {
// тело функции
}
function b() {
// тело функции
}
То же самое относится и к файлам, содержащим только классы PHP и ничего больше. Все же, по возможности, лучше держать файлы вне веб-каталога.
Вы можете случайно деактивировать PHP, и в этом случае ваш сервер может отправить содержимое файлов PHP браузеру, вместо того чтобы запустить PHP и отправить результат. Это может привести к утечке вашего кода (включая пароли баз данных, ключи API и т.д.).
Файлы в веб-каталоге соответствуют URL-адресам, которые вы, возможно, захотите использовать для своего приложения. Я работаю с CMS, в которой не может быть страницы с названием system, потому что это противоречит пути, используемому для кода.
Web