Запретить прямой доступ к файлу php - PullRequest
155 голосов
/ 03 января 2009

У меня есть php-файл, который я буду использовать исключительно для включения. Поэтому я хотел бы выдать ошибку вместо того, чтобы выполнить ее, когда к ней обращаются напрямую, введя URL-адрес вместо включения.

В основном мне нужно выполнить проверку в php-файле следующим образом:

if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");

Есть ли простой способ сделать это?

Ответы [ 34 ]

4 голосов
/ 23 января 2012
debug_backtrace() || die ("Direct access not permitted");
4 голосов
/ 08 ноября 2017

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

if (empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && $_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") {
    if (realpath($_SERVER["SCRIPT_FILENAME"]) == __FILE__) { // direct access denied
        header("Location: /403");
        exit;
    }
}
4 голосов
/ 03 января 2009

Самый простой способ - установить некоторую переменную в файле, который вызывает include, например,

$including = true;

Затем в включаемом файле проверьте переменную

if (!$including) exit("direct access not permitted");
3 голосов
/ 04 января 2009

Помимо способа .htaccess, я видел полезный шаблон в различных фреймворках, например в ruby ​​on rails. У них есть отдельный каталог pub / в корневом каталоге приложения, а каталоги библиотеки находятся в каталогах на уровне , что и pub /. Примерно так (не идеально, но вы поняли):

app/
 |
 +--pub/
 |
 +--lib/
 |
 +--conf/
 |
 +--models/
 |
 +--views/
 |
 +--controllers/

Вы настроили свой веб-сервер на использование pub / в качестве корня документа. Это обеспечивает лучшую защиту ваших сценариев: хотя они могут обращаться к корневому каталогу документа для загрузки необходимых компонентов, невозможно получить доступ к компонентам из Интернета. Еще одно преимущество, помимо безопасности, заключается в том, что все в одном месте.

Эта настройка лучше, чем просто создание проверок в каждом отдельном включенном файле, потому что сообщение «доступ запрещен» является подсказкой для злоумышленников, и оно лучше, чем конфигурация .htaccess, поскольку оно не основано на белом списке: если вы облажаетесь Расширения файлов не будут видны в каталогах lib /, conf / etc..

2 голосов
/ 09 мая 2015

Если точнее, вы должны использовать это условие:

if (array_search(__FILE__, get_included_files()) === 0) {
    echo 'direct access';
}
else {
    echo 'included';
}

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

1 голос
/ 06 декабря 2013

Мой ответ несколько отличается в подходе, но включает в себя многие ответы, представленные здесь. Я бы порекомендовал многоплановый подход:

  1. .htaccess и ограничения Apache наверняка
  2. defined('_SOMECONSTANT') or die('Hackers! Be gone!');

ОДНАКО Подход defined or die имеет ряд недостатков. Во-первых, это реальная боль в предположениях, с которыми нужно тестировать и отлаживать. Во-вторых, если вы передумаете, это будет ужасающе, ошеломляюще скучным рефакторингом. "Найти и заменить!" ты говоришь. Да, но насколько вы уверены, что везде написано одно и то же, хммм? Теперь умножьте это на тысячи файлов ... o.O

А потом есть .htaccess. Что произойдет, если ваш код распространяется на сайты, где администратор не так скрупулезен? Если вы полагаетесь только на .htaccess для защиты своих файлов, вам также понадобятся: а) резервная копия, б) ящик для салфеток, чтобы высушить ваши слезы, в) огнетушитель для тушения пламени во всей ненависти от людей используя ваш код.

Так что я знаю, что вопрос требует «самого простого», но я думаю, что это требует более «защитного кодирования».

Я предлагаю следующее:

  1. Перед любым из ваших сценариев require('ifyoulieyougonnadie.php'); ( не include() и в качестве замены defined or die)
  2. В ifyoulieyougonnadie.php выполните некоторые логические операции - проверьте различные константы, вызовите скрипт, тестируйте локальный хост и т. Д., А затем реализуйте die(), throw new Exception, 403 и т. Д.

    Я создаю свой собственный фреймворк с двумя возможными точками входа - основной index.php (фреймворк Joomla) и ajaxrouter.php (мой фреймворк) - поэтому в зависимости от точки входа я проверяю разные вещи. Если запрос на ifyoulieyougonnadie.php не приходит из одного из этих двух файлов, я знаю, что махинации предпринимаются!

    Но что, если я добавлю новую точку входа? Не волнуйтесь. Я просто изменяю ifyoulieyougonnadie.php, и я отсортирован, плюс нет «найти и заменить». Ура!

    Что, если я решил переместить некоторые из моих сценариев для создания другой среды, которая не имеет одинаковых констант defined()? ... Ура! ^ _ ^

Я обнаружил, что эта стратегия делает разработку намного веселее и намного меньше:

/**
 * Hmmm... why is my netbeans debugger only showing a blank white page 
 * for this script (that is being tested outside the framework)?
 * Later... I just don't understand why my code is not working...
 * Much later... There are no error messages or anything! 
 * Why is it not working!?!
 * I HATE PHP!!!
 * 
 * Scroll back to the top of my 100s of lines of code...
 * U_U
 *
 * Sorry PHP. I didn't mean what I said. I was just upset.
 */

 // defined('_JEXEC') or die();

 class perfectlyWorkingCode {}

 perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();
1 голос
/ 18 июля 2010

Следующий код используется в Flatnux CMS (http://flatnux.altervista.org):

if ( strpos(strtolower($_SERVER['SCRIPT_NAME']),strtolower(basename(__FILE__))) )
{
    header("Location: ../../index.php");
    die("...");
}
1 голос
/ 01 октября 2013
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
1 голос
/ 07 мая 2010
<?php
if (eregi("YOUR_INCLUDED_PHP_FILE_NAME", $_SERVER['PHP_SELF'])) { 
 die("<h4>You don't have right permission to access this file directly.</h4>");
}
?>

Поместите код выше в верхней части вашего включенного файла php.

например:

<?php
if (eregi("some_functions.php", $_SERVER['PHP_SELF'])) {
    die("<h4>You don't have right permission to access this file directly.</h4>");
}

    // do something
?>
0 голосов
/ 27 мая 2017

Перенаправить из этого файла на другую страницу. (например, index.html)

.htaccess:

Redirect 301 LINK_TO_YOUR_PHP LINK_TO_INDEX.HTML
...