У меня есть php-файл, который я буду использовать исключительно как include. Поэтому я хотел бы сделать ошибку, а не выполнять ее, когда она будет доступна напрямую, введя URL вместо того, чтобы быть включенным.
В основном мне нужно сделать проверку в файле php следующим образом:
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
Есть простой способ сделать это?
Самый простой способ для общего «PHP-приложения, работающего на сервере Apache, который вы можете или не можете полностью контролировать», – это включить ваши включения в каталог и запретить доступ к этому каталогу в вашем файле .htaccess. Чтобы спасти людей от проблем с Google, если вы используете Apache, поместите это в файл с именем «.htaccess» в каталог, который вы не хотите быть доступным:
Deny from all
Если на самом деле у вас есть полный контроль над сервером (чаще всего в эти дни даже для небольших приложений, чем при первом написании этого ответа), лучший подход заключается в том, чтобы вставлять файлы, которые вы хотите защитить, за пределами каталога, на котором работает ваш веб-сервер , Поэтому, если ваше приложение находится в /srv/YourApp/
, установите сервер для работы с файлами из /srv/YourApp/app/
и поместите /srv/YourApp/includes
в /srv/YourApp/includes
, так что там буквально нет ни одного URL-адреса, который может получить к ним доступ ,
Добавьте это на страницу, которую хотите только включить
<?php if(!defined('MyConst')) { die('Direct access not permitted'); } ?>
затем на страницах, которые включают его, добавьте
<?php define('MyConst', TRUE); ?>
У меня есть файл, который мне нужно действовать по-другому, когда он включен vs, когда он доступен напрямую (в основном, print()
vs return()
). Вот некоторые модифицированные коды:
if(count(get_included_files()) ==1) exit("Direct access not permitted.");
Доступ к файлу всегда является включенным файлом, следовательно, == 1.
Лучший способ предотвратить прямой доступ к файлам – разместить их вне корня документа веб-сервера (обычно на одном уровне выше). Вы можете включить их, но нет возможности получить доступ к ним через HTTP-запрос.
Я обычно прохожу весь путь и размещаю все мои файлы PHP за пределами корня документа, кроме файла начальной загрузки, – одиночного index.php в корневом каталоге документа, который начинает маршрутизацию всего веб-сайта / приложения.
Альтернативой (или дополнением) к решению Чака было бы запретить доступ к файлам, соответствующим определенному шаблону, помещая что-то подобное в ваш .htaccess файл
<FilesMatch "\.(inc)$"> Order deny,allow Deny from all </FilesMatch>
На самом деле мой совет – сделать все эти лучшие практики.
if (!defined(INCL_FILE_FOO)) { header('HTTP/1.0 403 Forbidden'); exit; }
Таким образом, если файлы каким-то образом утеряны (ошибочная операция ftp), они все еще защищены.
if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) ) { exit(); }
Логика:
PHP5 + считает текущую страницу включенной.
Это делается в файле main.php, к которому пользователь может получить доступ напрямую:
$loopbackdata=file_get_contents("http://127.0.0.1/component.php?query=string");
Где component.php
– это файл, который вы не хотите, чтобы пользователь имел прямой доступ.
//VARS $dart="/error.php?errortype=direct_access_of_component"; //Description: Direct-Access Redirection Target //GET SOURCE OF REQUEST $src=$_SERVER['REMOTE_ADDR']; //VALIDATE SOURCE(COMPARE AGAINST AUTHORIZED FRONT-END SERVER ADDRESSES) $auth=false; switch($src){ case "localhost": case "127.0.0.1": case "192.168.0.1": $auth=true; break; default: $auth=false; } //IF NOT AUTHENTICATED, EXIT: if(!$auth){header("Location: ".$dart);exit();} //ELSE PROCEED WITH CODE
Разбор строки с использованием php. И снова, наконец:
if($key!="serv97602"){header("Location: ".$dart);exit();}
Такой метод может использоваться в случаях, когда доступ к файлу с включенным PHP-кодом является условным, возможно, основанным на сеансах или уровне авторизации. Очень грязный метод, но также, возможно, самый безопасный и универсальный в то же время, когда он используется правильно.
Большинство серверов позволяют назначать разрешения для отдельных файлов или каталогов. Вы можете разместить все свои включения в таких ограниченных каталогах и настроить сервер на отказ от них.
Например, в APACHE конфигурация сохраняется в файле .htaccess
. Учебник здесь .
Обратите внимание, однако, что настройки, специфичные для сервера, мне не рекомендуются, потому что они плохо переносимы на разных веб-серверах. В таких случаях, когда алгоритм deny является сложным или список запрещенных каталогов довольно велик, он может сделать сеансы реконфигурации довольно ужасными. В конце концов, лучше всего обработать это в коде.
Наименее предпочтительный из-за ограничений доступа в серверных средах, но довольно мощный метод, если у вас есть доступ к файловой системе.
//Your secure dir path based on server file-system $secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR; include($secure_dir."securepage.php");
Логика:
htdocs
поскольку ссылки будут htdocs
для адресной системы веб-сайта. Пожалуйста, извините мои плохие правила кодирования. Я не опытный разработчик PHP. Возможно, существуют лучшие методы. Любые отзывы о моем ответе приветствуются.
Однажды я столкнулся с этой проблемой, решив:
if (strpos($_SERVER['REQUEST_URI'], basename(__FILE__)) !== false) ...
но идеальным решением является размещение файла вне корневого документа веб-сервера, как указано в другом anwser.
Вам лучше создать приложение с одной точкой входа, то есть все файлы должны быть получены из index.php
Поместите это в index.php
define(A,true);
Эта проверка должна выполняться в каждом связанном файле (через require или include)
defined('A') or die(header('HTTP/1.0 403 Forbidden'));
Самый простой способ – установить некоторую переменную в файле, который включает include, например
$including = true;
Затем в файл, который включен, проверьте переменную
if (!$including) exit("direct access not permitted");
Что такое Joomla! is определяет константу в корневом файле и проверяет, определено ли это во входящих файлах.
defined('_JEXEC') or die('Restricted access');
или иначе
можно хранить все файлы вне досягаемости HTTP-запроса, размещая их вне каталога webroot, поскольку большинство фреймворков, таких как CodeIgniter, рекомендуют.
или даже путем размещения файла .htaccess внутри папки include и написания правил, вы можете предотвратить прямой доступ.
debug_backtrace() || die ("Direct access not permitted");
Помимо пути .htaccess, я видел полезную модель в различных рамках, например, в ruby on rails. У них есть отдельный каталог pub / в корневом каталоге приложения, а каталоги библиотек живут в каталогах на том же уровне, что и pub /. Что-то вроде этого (не идеально, но вы поняли):
app/ | +--pub/ | +--lib/ | +--conf/ | +--models/ | +--views/ | +--controllers/
Вы настроили свой веб-сервер для использования pub / as root. Это обеспечивает лучшую защиту ваших скриптов: в то время как они могут протянуться из корня документа для загрузки необходимых компонентов, невозможно получить доступ к компонентам из Интернета. Еще одно преимущество, помимо безопасности, заключается в том, что все в одном месте.
Эта настройка лучше, чем просто создание проверок в каждом отдельном файле, потому что сообщение «доступ не разрешено» является подсказкой для злоумышленников, и это лучше, чем настройка .htaccess, потому что это не белый список: если вы испортили расширения файлов он не будет отображаться в каталогах lib /, conf / etc.
Если точнее, вы должны использовать это условие:
if (array_search(__FILE__, get_included_files()) === 0) { echo 'direct access'; } else { echo 'included'; }
get_included_files () возвращает индексированный массив, содержащий имена всех включенных файлов (если файл beign выполнен, то он был включен и его имя находится в массиве). Итак, когда файл имеет прямой доступ, его имя является первым в массиве, все остальные файлы в массиве были включены.
<?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 ?>
Следующий код используется в CMS Flatnux ( http://flatnux.altervista.org ):
if ( strpos(strtolower($_SERVER['SCRIPT_NAME']),strtolower(basename(__FILE__))) ) { header("Location: ../../index.php"); die("..."); }
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
Мой ответ несколько отличается в подходе, но включает в себя многие из приведенных здесь ответов. Я бы рекомендовал многопрофильный подход:
defined('_SOMECONSTANT') or die('Hackers! Be gone!');
ОДНАКО, что defined or die
подход имеет ряд недостатков. Во-первых, это настоящая боль в предположениях для тестирования и отладки. Во-вторых, это связано с ужасающим, умопомрачительно скучным рефакторингом, если вы передумаете. "Найти и заменить!" ты говоришь. Да, но насколько ты уверен, что все написано точно так же везде, хммм? Теперь умножьте это на тысячи файлов … oO
И тогда есть .htaccess. Что произойдет, если ваш код будет распространен на сайтах, где администратор не так скрупулезен? Если вы полагаетесь только на .htaccess для защиты ваших файлов, вам также понадобится: a) резервная копия, b) ящик тканей для высыхания ваших слез, c) огнетушитель, чтобы погасить огонь во всей ленте от людей используя ваш код.
Поэтому я знаю, что вопрос требует «самого легкого», но я думаю, что это требует более «защитного кодирования».
Я предлагаю:
require('ifyoulieyougonnadie.php');
любой из ваших сценариев require('ifyoulieyougonnadie.php');
( не include()
и в качестве замены для defined or die
) В ifyoulieyougonnadie.php
, сделайте некоторые логические вещи – проверьте разные константы, ifyoulieyougonnadie.php
скрипт, тестирование localhost и т. Д., А затем выполните свой die(), throw new Exception, 403
введите die(), throw new Exception, 403
и т. Д.
Я создаю свою собственную фреймворк с двумя возможными точками входа – основной index.php (структура Joomla) и ajaxrouter.php (my framework) – поэтому в зависимости от точки входа я проверяю разные вещи. Если запрос на 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();
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
сделает работу гладкой
Я хотел напрямую ограничить доступ к файлу 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; } }
Сделайте что-то вроде:
<?php if ($_SERVER['SCRIPT_FILENAME'] == '<path to php include file>') { header('HTTP/1.0 403 Forbidden'); exit('Forbidden'); } ?>
Я нашел это php-only и неизменное решение, которое работает как с http, так и с cli:
Определить функцию:
function forbidDirectAccess($file) { $self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/"); (substr_compare($file, $self, -strlen($self)) != 0) or die('Restricted access'); }
Вызовите функцию в файле, для которого вы хотите запретить прямой доступ:
forbidDirectAccess(__FILE__);
Большинство решений, приведенных выше в этом вопросе, не работают в режиме Cli.
Вы можете использовать следующий ниже метод, хотя у него есть недостаток, потому что его можно подделать, за исключением случаев, когда вы можете добавить еще одну строку кода, чтобы убедиться, что запрос приходит только с вашего сервера либо с помощью Javascript. Вы можете поместить этот код в раздел «Тело» вашего HTML-кода, поэтому там отображается ошибка.
<? if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); } else { ?>
Поместите свой другой HTML-код здесь
<? } ?>
Завершите это так, поэтому вывод ошибки всегда будет отображаться внутри секции тела, если вы так хотите.
Я предлагаю не использовать $_SERVER
по соображениям безопасности.
Вы можете использовать переменную типа $root=true;
в первом файле, который включал еще один.
и используйте isset($root)
в начале второго файла, который будет включен.
То, что вы также можете сделать, это защитить паролем каталог и сохранить все ваши php-скрипты там, конечно, за исключением файла index.php, поскольку на момент включения пароля пароль не требуется, поскольку он будет необходим только для доступа к http. то, что он будет делать, также предоставляет вам возможность доступа к вашим скриптам в случае, если вы этого хотите, поскольку у вас будет пароль для доступа к этому каталогу. вам нужно будет установить файл .htaccess для каталога и файл .htpasswd для аутентификации пользователя.
хорошо, вы также можете использовать любое из вышеперечисленных решений, если вы считаете, что вам не нужно обращаться к этим файлам, потому что вы всегда можете получить к ним доступ через cPanel и т. д.
Надеюсь это поможет
Самый простой способ заключается в том, чтобы хранить ваши ресурсы вне веб-каталога. Таким образом, у сервера есть доступ к ним, но нет внешней машины. Единственная нижняя сторона – вам нужно иметь доступ к этой части вашего сервера. Поверхность – это не требует настройки, конфигурации или дополнительного стресса кода / сервера.
<?php $url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']; if (false !== strpos($url,'.php')) { die ("Direct access not premitted"); } ?>
Я не нашел предложений с хорошим .htaccess, потому что он может блокировать другое содержимое в этой папке, которое вы, возможно, захотите разрешить пользователю, – это мое решение:
$currentFileInfo = pathinfo(__FILE__); $requestInfo = pathinfo($_SERVER['REQUEST_URI']); if($currentFileInfo['basename'] == $requestInfo['basename']){ // direct access to file }
Ранее упомянутое решение с проверкой версии PHP добавлено:
$max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1; if (count(get_included_files()) <= $max_includes) { exit('Direct access is not allowed.'); }
Вы можете использовать стиль phpMyAdmin:
/** * block attempts to directly run this script */ if (getcwd() == dirname(__FILE__)) { die('Attack stopped'); }