Есть ли способ предотвратить просмотр пользователем файла, но по-прежнему использовать его как включенный в другой файл в PHP?
PHP: проверьте, загружен ли файл напрямую, а не включен?
Ответ 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
*/
?>
Ответ 15
Вы должны использовать расширение PHP для расширителя кодера и загрузчика:
Коммерческая
Free
- eAccelerator
- Монасты (ранее на http://ombudi.com/)