Как определить, включен ли файл или запущен напрямую - PullRequest
4 голосов
/ 27 апреля 2011

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

Ответы [ 6 ]

5 голосов
/ 27 апреля 2011

Сделать включенные скрипты вообще недоступными по HTTP . Например. защищая подпапку или перемещая их над корнем документа.

Если вы не можете сделать это, define() что-то вроде IS_INCLUDED в вашем основном скрипте и exit;, если эта константа не defined() во включенном вами скрипте.

4 голосов
/ 05 января 2014

Проверка, является ли сценарий родительским процессом PHP, может быть не самой лучшей идеей для предотвращения непосредственного запроса пользователями включаемого файла. Но это может быть полезно во многих других случаях, т. Е. Модулях AJAX и т. Д. Я не собираюсь начинать новую тему этим.

if (__FILE__ == get_included_files()[0])
// Doesn't work with PHP prepend unless calling [1] instead.

if (__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME'])
// May not work on Windows due to mixed DIRECTORY_SEPARATOR (machine specific)

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']))
// Doesn't work with files with the same basename but different paths

if (defined('FLAG_FROM_A_PARENT'))
// Works in all scenarios but I personally dislike this

if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME']))
// Should work flawlessly

Имейте в виду, что некоторые машины, использующие виртуальные пути, могут возвращать разные пути в разных компонентах php. realpath () ваш друг для этого.

3 голосов
/ 27 апреля 2011

Я использую константу sentinel , определенную в сценарии «включающий», и сценарий «включенный» ищет его.

Пример:

/* main.php */
define('SENTINEL', 1);
include "included.inc.php"

/* included.inc.php */
if (!defined('SENTINEL')) die("Wanted to be smart?? Nice try.");
2 голосов
/ 11 июля 2013

2 решения для хорошей защиты:

  1. Apache

с htaccess :

RedirectMatch 404 "\.(sql|sh|java|class|inc\.php)$"

Или в / etc / apache2 / sites-enabled :

<VirtualHost *:80>
#...
RedirectMatch 404 "\.(sql|sh|java|class|inc\.php)$"
#...
</VirtualHost>

Затем назовите свой файл так: myInternalFileIncludeOnly.inc.php

  1. PHP

С помощью этого примера кода PHP может обнаружить:

if( get_included_files()[0] == __FILE__ ){
    echo '2.php direct access';
}else{
    echo '2.php was included';
}

EDIT : Смотрите ответ Тим, так что если у вас есть prepend include (cf php.ini), используйте это:

if(
    (!ini_get('auto_prepend_file') && get_included_files()[0] === __FILE__)
    ||
    ini_get('auto_prepend_file') && (($__FILE__=str_replace('\\','/',__FILE__)) === str_replace('\\','/',$_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_FILENAME']) || $__FILE__ === str_replace('\\','/',$_SERVER['SCRIPT_FILENAME']) )
)
    echo '2.php direct access',"\n";
1 голос
/ 27 апреля 2011

Я видел этот шаблон в некоторых приложениях:

  1. Основной, запускаемый файл запускается напрямую define('SOMETHING', 'SOMEVALUE');
  2. Включенный файл начинается с if(!defined('SOMETHING')) return;
0 голосов
/ 27 апреля 2011

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

Запуск их напрямую - это, по сути, запрет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...