Подтвердить что ты не робот

PHP: проверьте, загружен ли файл напрямую, а не включен?

Есть ли способ предотвратить просмотр пользователем файла, но по-прежнему использовать его как включенный в другой файл в PHP?

4b9b3361

Ответ 1

Если вы используете

define('APP_RAN'); 

в файле, который включает его, а затем поместите

if(!defined('APP_RAN')){ die(); }

или, альтернативно,

defined('APP_RAN') or die();

(что легче читать)

в включенных файлах он будет умирать, если вы получите доступ к ним напрямую.


Скорее всего, лучше разместить все ваши включенные файлы выше вашего DocumentRoot.

Например, если ваша индексная страница находится в

/my/server/domain/public_html

Вы должны поместить включенные файлы в

/my/server/domain/

Ответ 2

Не используйте глобальный код в своих файлах, только функции и методы. Тогда не будет необходимости заботиться о включении и прямом использовании.

Ответ 3

Мое предложение:

<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
    exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>404 Not Found</title>\r\n</head><body>\r\n<h1>Not Found</h1>\r\n<p>The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on this server.</p>\r\n</body></html>");
}
else {
   // your code
}
?>

1.) он проверяет, вызван ли он непосредственно иначе, он выдает ошибку

2.) он выдает 404 стандартную страницу ошибки apache (пожалуйста, сравните с вашей оригинальной страницей 404 или просто включите эту страницу), чтобы добавить защиту через неявку

3.) Другая часть позволяет избежать частичного выполнения, пока файл загружается в среду live (PHP не ждет "? > " ). Это вам не нужно, если ваш включенный файл содержит только одну функцию/один класс.

Ответ 4

Просто сохраните файл за пределами вашего веб-корня.

Ответ 5

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

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 break on Windows due to mixed DIRECTORY_SEPARATOR

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

if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']))
// Seems to do the trick

Ответ 6

if (__FILE__ == $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']){
  die("Direct access forbidden");
}

Он работает независимо от того, где он находится. (Приветствует @col-sharpnel за то, что указывает на неполное, но хорошее решение.)

Ответ 7

Здесь функция get_included_files. Вы можете использовать его так:

if ( empty(get_included_files()) ) die("Direct access forbidden");

Ответ 8

В Apache это легко: добавьте директиву <Files> в свой .htaccess, чтобы предотвратить доступ к нему из веб-браузера. Это не относится к PHP includes, и рекомендуется скрыть несколько файлов из браузера (хотя обычно вы пытаетесь объединить все не доступные файлы в один каталог).

<Files="myprivatefile.php">
    deny from all
</Files>

Под другим веб-сервером вы можете скрыть файл из корня документа, но в некоторых случаях (например, если ваши сценарии open_basedir 'd строгим образом), это не сработает.

Ответ 9

if($argv[0] == basename(__FILE__))
    include_once('/path/to/file.php');

Ответ 10

Проверьте, сколько там файлов включено...

if(count(get_required_files()) < 2) { die(); }

Или сколько минимум должно быть, а не 2

Ответ 11

В этой теме много хороших ответов - здесь еще не упомянуто.

Вы можете назвать ваши включенные PHP файлы с помощью i в расширении, например. someincludedfile.phpi, а затем настройте Apache так, чтобы он не обслуживал файлы phpi. Вуаля.

Минусы:

  • (!) сильно зависит от конфигурации Apache (так что вы уязвимы, если кто-то пренебрегает этой строкой) - и в таком случае браузер может увидеть весь PHP script в виде открытого текста, t передается PHP (очень плохо!)
  • Это может раздражать, чтобы переименовать ваши включенные файлы.

Плюсы:

  • дает понять, какие файлы должны быть включены, а какие нет в вашем коде.
  • вам не нужно перемещать иерархию файлов вокруг

Лично я предпочел бы просто перемещать файлы в каталог за пределами корня документа, но если у вас есть большое унаследованное приложение, это можно было бы быстрее изменить.

Ссылка: http://www.ducea.com/2006/07/21/apache-tips-tricks-deny-access-to-certain-file-types/

Ответ 12

Я бы выбрал решение Chacha102.

Кроме того, поскольку ваш заголовок вопроса говорит "как проверить", вы также можете сделать это без необходимости определять переменную с помощью

// secret.php is the name of this file.
if($_SERVER["SCRIPT_FILENAME"]=='secret.php') die();

Ответ 13

Если вы хотите остановить его из когда-либо отображаемого, если он не включен здесь более автоматизированным способом.

if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) header("HTTP/1.0 404 Not Found");

Таким образом, он будет работать, если вы в конечном итоге измените имя файла или что-то еще.

Ответ 14

Просто для расширения решений с переменными $_SERVER - ниже - маленький .php файл, а в комментариях - это копия теста bash, который я сделал на Ubuntu; Дело в том, что эти переменные могут сильно изменяться в зависимости от типа доступа и используются ли символические ссылки (кроме того, в приведенном ниже коде я должен избегать "?\>" в выражении echo, иначе цвет синтаксиса прерывается, удалите обратную косую черту, если пытаетесь выполнить код):

<?php

function report($label, $value) {
  printf ("%23s: %s\n", $label, $value);
}

report("DOCUMENT_ROOT.PHP_SELF",  $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'] );
report("SCRIPT_FILENAME",         $_SERVER['SCRIPT_FILENAME'] );
report("__FILE__",                __FILE__ );
report("PHP_SAPI",                PHP_SAPI );

/*
# the test (bash):

home~$ mkdir /tmp/ptest
home~$ cd /tmp/ptest/
ptest$ ln -s /real/path/to/varcheck.php .
ptest$ echo '<? require_once "varcheck.php"; ?\>' > varcheckincl.php


# ... and in a separate terminal, run
# php (>5.4) cli server at same (/tmp/ptest) location:

ptest$ php-5.4.10 -S localhost:8000

# back to first terminal, the test - and output:

ptest$ php varcheck.php
 DOCUMENT_ROOT.PHP_SELF: varcheck.php
        SCRIPT_FILENAME: varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php -r 'require_once "varcheck.php";'
 DOCUMENT_ROOT.PHP_SELF: -
        SCRIPT_FILENAME:
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php varcheckincl.php
 DOCUMENT_ROOT.PHP_SELF: varcheckincl.php
        SCRIPT_FILENAME: varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ wget http://localhost:8000/varcheck.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheck.php
        SCRIPT_FILENAME: /tmp/ptest/varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server

ptest$ wget http://localhost:8000/varcheckincl.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheckincl.php
        SCRIPT_FILENAME: /tmp/ptest/varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server
*/
?>