Немного о компьютере

Безвозвратный user info php. Простой RESTful-сервис на нативном PHP. Извлечение переменной окружения HTTP_X_FORWARDED_FOR

Те, кто более-менее серьёзно изучал PHP знают, что существует один очень полезный глобальный массив в PHP , который называется $_SERVER . И вот хотелось бы в этой статье разобрать самые популярные ключи и их значения в этом массиве, так как их знание просто обязательно даже для начинающего PHP-программиста .

Прежде чем приступить к глобальному массиву $_SERVER в PHP , сразу сделаю небольшую подсказку. Есть замечательная функция, встроенная в PHP , которая называется phpinfo() . Давайте сразу приведу пример её использования:

phpinfo();
?>

В результате выполнения этого просто скрипта Вы увидите огромную таблицу с различными настройками интерпритатора PHP , в том числе, ближе к концу будет таблица значений глобального массива $_SERVER . Там будут перечислены все ключи и все соответствующие им значения. Чем это может Вам помочь? А тем, что если Вам потребуется то или иное значение, и Вы забудете, как называется ключ, то с помощью функции phpinfo() Вы можете всегда вспомнить его название. В общем, Вы выполните этот скрипт и сразу меня поймёте.

А теперь давайте перейдём к самым популярным ключам массива $_SERVER :

  • HTTP_USER_AGENT - этот ключ позволяет узнать характеристику клиента. В большинстве случаев, это, безусловно, браузер, однако, не всегда. И опять же, если браузер, то какой, вот в этой переменной об этом можно и узнать.
  • HTTP_REFERER - содержит абсолютный путь к тому файлу (PHP-скрипт , HTML-страница ), с которого перешли на данный скрипт. Грубо говоря, откуда пришёл клиент.
  • SERVER_ADDR - IP-адрес сервера.
  • REMOTE_ADDR - IP-адрес клиента.
  • DOCUMENT_ROOT - физический путь к корневой директории сайта. Это опция задаётся через конфигурационный файл сервера Apache .
  • SCRIPT_FILENAME - физический путь к вызванному скрипту.
  • QUERY_STRING - весьма полезное значение, которое позволяет получить строку с запросом, а дальше можно заниматься парсингом этой строки.
  • REQUEST_URI - ещё более полезное значение, которое содержит не только сам запрос, но и вместе с ним относительный путь к вызываемому скрипту от корня. Это очень часто используется для удаления дублирования с index.php , то есть когда у нас такой URL : "http://mysite.ru/index.php " и "http://mysite.ru/ " ведут на одну страницу, а URLы разные, следовательно, дублирование, что плохо скажется на поисковой оптимизации. И вот с помощью REQUEST_URI мы можем определить: с index.php или нет был вызван скрипт. И можем сделать редирект с index.php (если он присутствовал в REQUEST_URI ) на без index.php . В результате, при передаче такого запроса: "http://mysite.ru/index.php?id=5 ", у нас будет происходить редирект на URL : "http://mysite.ru/?id=5 ". То есть мы избавились от дублирования, удалив из URL этот index.php .
  • SCRIPT_NAME - относительный путь к вызываемому скрипту.

Пожалуй, это все элементы глобального массива $_SERVER в PHP , которые используются регулярно. Их надо знать и уметь использовать, когда это необходимо.

Во втором уроке мы напишем еще два класса и полностью закончим внутреннюю часть скрипта.

План

Цель серии уроков создать простое приложение, которое позволяет пользователям регистрироваться, входить, выходить и менять настройки. Класс, который будет содержать всю информации о пользователе будет называться User и он будет определен в файле User.class.php. Класс, который будет отвечать за вход\выход будет называться UserTools (UserTools.class.php).

Немного про именование классов

Правильным тоном является называть файлы с описанием класса таким же именем как и сам класс. Таким образом легко определить цель каждого файла в папке с классами.

Также обычно в конце названия файла класса добавляют.class или.inc. Таким образом мы четко определяем предназначение файла и можем с помощью.htaccess ограничить доступ к этим файлам.

Класс Пользователей (User.class.php)

Этот класс будет определять каждого пользователя. С ростом данного приложения определение "Пользователь" может существенно измениться. К счастью, ООП программирование позволяет легко добавлять дополнительные атрибуты пользователей.

Конструктор

В этом классе мы будем использовать конструктор - это функция, которая автоматически вызывается при создании очередной копии класса. Это позволяет нам автоматически публиковать некоторые атрибуты после создания проекта. В этом классе конструктор будет брать единственный аргумент: ассоциативный массив, который содержит один ряд из таблицы users нашей БД.

require_once "DB.class.php"; class User { public $id; public $username; public $hashedPassword; public $email;
public $joinDate;
//Конструктор вызывается при создании нового объекта //Takes an associative array with the DB row as an argument. function __construct($data) { $this->id = (isset($data["id"])) ? $data["id"] : ""; $this->username = (isset($data["username"])) ? $data["username"] : ""; $this->hashedPassword = (isset($data["password"])) ? $data["password"] : ""; $this->email = (isset($data["email"])) ? $data["email"] : ""; $this->joinDate = (isset($data["join_date"])) ? $data["join_date"] : ""; }
public function save($isNewUser = false) { //create a new database object. $db = new DB(); //if the user is already registered and we"re //just updating their info. if(!$isNewUser) { //set the data array $data = array("username" => ""$this->username"", "password" => ""$this->hashedPassword"",
"email" => ""$this->email"");
//update the row in the database $db->update($data, "users", "id = ".$this->id); }else { //if the user is being registered for the first time. $data = array("username" => ""$this->username"", "password" => ""$this->hashedPassword"", "email" => ""$this->email"", "join_date" => """.date("Y-m-d H:i:s",time())."""); $this->id = $db->insert($data, "users"); $this->joinDate = time(); } return true; } } ?>

Объяснение

Первая часть кода, вне зоны класса, обеспечивает подключение класса в БД (поскольку в классе User есть функция, которая требует этот класс).

Вместо переменных класса “protected” (использовались в 1-м уроке) мы определяем их как “public”. Это означает, что любой код вне класса имеет доступ к этим переменным при работе с объектом User.

Конструктор берет массив, в котором колонки в таблице являются ключами. Мы задаем переменную класса используя $this->variablename. В примере данного класса, мы прежде всего проверяем существует ли значение определенного ключа. Если да, тогда мы приравниваем переменную класса к этому значению. В противном случае - пустая строка. Код использует краткую форму записи оборота if:

$value = (3 == 4) ? "A" : "B";

В данном примере мы проверяем равняется ли 3 четырем! Если да - тогда $value = “A”, нет - $value = “B”. В нашем примере результат $value = “B”.

Сохраняем Информацию о Пользователях в БД

Функция сохранения используется для внесения изменений в таблицу БД с текущими значениями в объекте User. Эта функция использует класс БД, который мы создали в первом уроке. Используя переменные класса, устанавливается массив $data. Если данные о пользователе сохраняются впервые, тогда $isNewUser передается как $true (по умолчанию false). Если $isNewUser = $true, тогда вызывается функция insert() класса DB. В противном случае вызывается функция update(). В обоих случаях информация от объекта user будет сохранена в БД.

Класс UserTools.class.php

Этот класс будет содержать функции, которые имеют отношение к пользователям: login(), logout(), checkUsernameExists() и get(). Но с расширением данного приложения, Вы можете добавить еще множество других.

//UserTools.class.php require_once "User.class.php"; require_once "DB.class.php";
class UserTools {
//Log the user in. First checks to see if the //username and password match a row in the database. //If it is successful, set the session variables //and store the user object within.
public function login($username, $password)
{
$hashedPassword = md5($password); $result = mysql_query("SELECT * FROM users WHERE username = "$username" AND password = "$hashedPassword""); if(mysql_num_rows($result) == 1) { $_SESSION["user"] = serialize(new User(mysql_fetch_assoc($result))); $_SESSION["login_time"] = time(); $_SESSION["logged_in"] = 1; return true; }else{ return false; } }
//Log the user out. Destroy the session variables. public function logout() { unset($_SESSION["user"]); unset($_SESSION["login_time"]); unset($_SESSION["logged_in"]); session_destroy(); } //Check to see if a username exists. //This is called during registration to make sure all user names are unique. public function checkUsernameExists($username) { $result = mysql_query("select id from users where username="$username""); if(mysql_num_rows($result) == 0) { return false; }else{ return true; }
}
//get a user //returns a User object. Takes the users id as an input public function get($id) { $db = new DB(); $result = $db->select("users", "id = $id"); return new User($result); } }
?>

Функция login()

Функция login() понятна по названию. Она берет аргументы пользователя $username и $password и проверяет их соответствие. Если все совпадает, создает объект User со всей информацией и сохраняет его в сессии. Обратите внимание, что мы только используем функцию PHP serialize(). Она создает сохраненный вариант объекта, который можно легко отменить с помощью unserialize(). Также время логина будет сохранено. Это может использоваться в дальнейшем для предоставления пользователям информации о длительности пребывания на сайте.

Вы также можете заметить, что мы выставляем $_SESSION["logged_in"] на 1. Это позволяет нам легко проверить на каждой странице залогинен ли пользователь. Достаточно проверить только эту переменную.

Функция logout()

Также простая функция. Функция PHP unset() очищает переменные в памяти, в то время как session_destroy() удалит сессию.

Функция checkUsernameExists()

Кто знает английский легко поймет функцию. Она просто запрашивает БД, использован ли подобный логин или нет.

Функция get()

Эта функция берет уникальный id пользователя и делает запрос к БД с помощью класса DB, а именно функции select(). Она возьмет ассоциативный массив с рядом информации о пользователе и создаст новый объект User, передавая массив конструктору.

Где можно это использовать? К примеру, если Вы создадите страницу, которая должна отображать специфические профили пользователей, Вам необходимо будет динамически брать эту информацию. Вот так Вы можете это сделать: (допустим УРЛ http://www.website.com/profile.php?userID=3)

//note: you will have to open up a database connection first. //see Part 1 for further information on doing so. //You"ll also have to make sure that you"ve included the class files.
$tools = new UserTools(); $user = $tools->get($_REQUEST["userID"]); echo "Username: ".$user->username.""; echo "Joined On: ".$user->joinDate."";

Легко! Правда?

Последний штрих серверной части: global.inc.php

global.inc.php необходим для каждой страницы сайта. Почему? Таким образом мы разместим все обычные операции, которые нам понадобятся на странице. К примеру, мы начнем session_start(). Соединение с БД также откроется.

require_once "classes/UserTools.class.php";
require_once "classes/DB.class.php";
//connect to the database $db = new DB(); $db->connect();
//initialize UserTools object $userTools = new UserTools(); //start the session
session_start();
//refresh session variables if logged in if(isset($_SESSION["logged_in"])) { $user = unserialize($_SESSION["user"]); $_SESSION["user"] = serialize($userTools->get($user->id)); } ?>

Что он делает?

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

После соединения, мы начинаем функцию session_start(). Функция создает сессию или продолжает текущую, если пользователь уже залогинен. Поскольку наше приложение рассчитано на то, чтобы пользователи входили\выходили, эта функция обязательна на каждой странице.

Далее мы проверяем залогинен ли юзер. Если да - мы обновим $_SESSION["user"], чтобы отображать самую последнюю информацию о юзере. К примеру, если пользователь меняет свой емейл, в сессии будет храниться еще старый. Но с помощью авто обновления такого не случится.

На этом вторая часть подошла к концу! Завтра ожидайте заключительный урок по этой теме.

Всего наилучшего!

$HTTP_SERVER_VARS [удалено]

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

$_SERVER -- $HTTP_SERVER_VARS [удалено] Информация о сервере и среде исполнения

Описание

Переменная $_SERVER - это массив, содержащий информацию, такую как заголовки, пути и местоположения скриптов. Записи в этом массиве создаются веб-сервером. Нет гарантии, что каждый веб-сервер предоставит любую из них; сервер может опустить некоторые из них или предоставить другие, не указанные здесь. Тем не менее, многие эти переменные присутствуют в » спецификации CGI/1.1 , так что вы можете их ожидать их реализации и в конкретном веб-сервере.

Переменная $HTTP_SERVER_VARS содержит ту же начальную информацию, но она не суперглобальная . (Заметьте, что $HTTP_SERVER_VARS и $_SERVER являются разными переменными, так что PHP обрабатывает их соответственно). Также учтите, что "длинные массивы" были удалены в версии PHP 5.4.0, поэтому $HTTP_SERVER_VARS больше не существует.

Индексы

Вы можете найти (а можете и не найти) любой из следующих элементов в массиве $_SERVER . Заметьте, что немногие элементы, если вообще такие найдутся, будут доступны (или действительно будут иметь значение), если PHP запущен в командной строке .

" PHP_SELF " Имя файла скрипта, который сейчас выполняется, относительно корня документов. Например, $_SERVER["PHP_SELF"] в скрипте по адресу http://example.com/foo/bar.php будет /foo/bar.php . Константа __FILE__ содержит полный путь и имя файла текущего (то есть подключенного) файла. Если PHP запущен в командной строке, эта переменная содержит имя скрипта, начиная с PHP 4.3.0. Раньше она была недоступна. "argv " Массив аргументов, переданных скрипту. Когда скрипт запущен в командой строке, это дает C-подобный доступ к параметрам командной строки. Когда вызывается через метод GET, этот массив будет содержать строку запроса. "argc " Содержит количество параметров, переданных скрипту (если запуск произведен в командной строке). " GATEWAY_INTERFACE " Содержит используемую сервером версию спецификации CGI; к примеру"CGI/1.1 ". " SERVER_ADDR " IP адрес сервера, на котором выполняется текущий скрипт. " SERVER_NAME " Имя хоста, на котором выполняется текущий скрипт. Если скрипт выполняется на виртуальном хосте, здесь будет содержатся имя, определенное для этого виртуального хоста. " SERVER_SOFTWARE " Строка идентификации сервера, указанная в заголовках, когда происходит ответ на запрос. " SERVER_PROTOCOL " Имя и версия информационного протокола, через который была запрошена страница; к примеру "HTTP/1.0 "; " REQUEST_METHOD " Какой метод был использован для запроса страницы; к примеру "GET ", "HEAD ", "POST ", "PUT ".

Замечание :

PHP скрипт завершается после посылки заголовков (то есть после того, как осуществляет любой вывод без буферизации вывода), если запрос был осуществлен методом HEAD .

" REQUEST_TIME " Временная метка начала запроса. Доступна, начиная с PHP 5.1.0. " REQUEST_TIME_FLOAT " Временная метка начала запроса с точностью до микросекунд. Доступна, начиная с PHP 5.4.0. " QUERY_STRING " Строка запросов, если есть, с помощью которой была получена страница. " DOCUMENT_ROOT " Директория корня документов, в которой выполняется текущий скрипт, в точности та, которая указана в конфигурационном файле сервера. " HTTP_ACCEPT " Содержимое заголовка Accept: из текущего запроса, если он есть. " HTTP_ACCEPT_CHARSET " Содержимое заголовка Accept-Charset: из текущего запроса, если он есть. Например: "iso-8859-1,*,utf-8 ". " HTTP_ACCEPT_ENCODING " Содержимое заголовка Accept-Encoding: gzip ". " HTTP_ACCEPT_LANGUAGE " Содержимое заголовка Accept-Language: из текущего запроса, если он есть. Например: "en ". " HTTP_CONNECTION " Содержимое заголовка Connection: из текущего запроса, если он есть. Например: "Keep-Alive ". " HTTP_HOST " Содержимое заголовка Host: из текущего запроса, если он есть. " HTTP_REFERER " Адрес страницы (если есть), которая привела браузер пользователя на эту страницу. Этот заголовок устанавливается веб-браузером пользователя. Не все браузеры устанавливают его и некоторые в качестве дополнительной возможности позволяют изменять содержимое заголовка HTTP_REFERER . Одним словом, в самом деле ему нельзя доверять. " HTTP_USER_AGENT " Содержимое заголовка User-Agent: из текущего запроса, если он есть. Эта строка содержит обозначение браузера, которым пользователь запросил данную страницу. Типичным примером является строка: Mozilla/4.5 (X11; U; Linux 2.2.9 i586) . Среди прочего, вы можете использовать это значение с функцией get_browser() чтобы адаптировать вывод вашей страницы к возможностям браузера пользователя " HTTPS " Принимает непустое значение, если запрос был произведен через протокол HTTPS.

Замечание : Обратите внимание, что при использовании ISAPI с IIS значение будет off , если запрос не был произведен через протокол HTTPS.

" REMOTE_ADDR " IP-адрес, с которого пользователь просматривает текущую страницу. " REMOTE_HOST " Удаленный хост, с которого пользователь просматривает текущую страницу. Обратный просмотр DNS базируется на значении переменной REMOTE_ADDR .

Замечание : Ваш веб-сервер должен быть настроен, чтобы создавать эту переменную. Для примера, в Apache вам необходимо присутствие директивы HostnameLookups On в файле httpd.conf , чтобы эта переменная создавалась. См. также gethostbyaddr() .

" REMOTE_PORT " Порт на удаленной машине, который используется для связи с веб-сервером. " REMOTE_USER " Аутентифицированный пользователь. " REDIRECT_REMOTE_USER " Аутентифицированный пользователь, если запрос был перенаправлен изнутри. " SCRIPT_FILENAME "

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

Замечание :

Если скрипт запускается в командной строке (CLI), используя относительный путь, такой как file.php или../file.php , переменная $_SERVER["SCRIPT_FILENAME"] будет содержать относительный путь, указанный пользователем.

" SERVER_ADMIN " Эта переменная получает свое значение (для Apache) из директивы конфигурационного файла сервера. Если скрипт запущен на виртуальном хосте, это будет значение, определенное для данного виртуального хоста. " SERVER_PORT " Порт на компьютере сервера, используемый веб-сервером для соединения. Для установок по умолчанию, значение будет "80 "; используя SLL, например, это значение будет таким, какое сконфигурировано для соединений безопасного HTTP.

Замечание : Чтобы получить физический (реальный) порт в Apache 2, необходимо установить UseCanonicalName = On и UseCanonicalPhysicalPort = On , иначе это значение может быть подменено и не вернуть реальной значение физического порта. Полагаться на это значение небезопасно в контексте приложений, требующих усиленной безопасности.

" SERVER_SIGNATURE " Строка, содержащая версию сервера и имя виртуального хоста, которые добавляются к генерируемым сервером страницам, если включено. " PATH_TRANSLATED " Filesystem- (not document root-) based path to the current script, after the server has done any virtual-to-real mapping.

Замечание : Начиная с PHP 4.3.2, переменная PATH_TRANSLATED больше не устанавливается неявно в Apache 2 SAPI , по сравнению с Apache версии 1, где она устанавливается в то же самое значение, что и переменная SCRIPT_FILENAME , когда она не используется Apache. Это изменение было сделано для соответствия спецификации CGI , где переменная PATH_TRANSLATED должна существовать только тогда, когда PATH_INFO определена. Пользователи Apache 2 могут использовать директиву AcceptPathInfo = On в конфигурационном файле httpd.conf для задания переменной PATH_INFO .

" SCRIPT_NAME " Содержит путь, к текущему исполняемому скрипту. Это полезно для страниц, которые должны указывать на самих себя. Константа __FILE__ содержит полный путь и имя текущего (т.е. включаемого) файла. " REQUEST_URI " URI, который был передан для того, чтобы получить доступ к этой странице. Например, "/index.html ". " PHP_AUTH_DIGEST " При выполнении HTTP Digest аутентификации, этой переменной присваивается заголовок "Authorization", который присылается клиентом (его необходимо потом использовать для соответствующей валидации). " PHP_AUTH_USER " Когда выполняется HTTP-аутентификация, этой переменной присваивается имя пользователя, предоставленное пользователем. " PHP_AUTH_PW " Когда выполняется HTTP-аутентификация, этой переменной присваивается пароль, предоставленный пользователем. " AUTH_TYPE " Когда выполняется HTTP-аутентификация, этой переменной присваивается тип аутентификации, который используется. " PATH_INFO " Содержит любой предоставленный пользователем путь, содержащийся после имени скрипта, но до строки запроса, если доступно. Например, если текущий скрипт запрошен по URL http://www.example.com/php/path_info.php/some/stuff?foo=bar , то переменная $_SERVER["PATH_INFO"] будет содержать /some/stuff ?>

Результатом выполнения данного примера будет что-то подобное.

1 year ago | 9.8K

В программированию, очень часто встречается задача, когда нужно обратиться к другому сайту через HTTP или HTTPS. В этой статье мы рассмотрим простой способ, как с помощью языка программирования PHP выполнить данную задачу.

Для чего обращаться с помощью PHP через HTTP или HTTPS к другому сайту?

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

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

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

Пример обращения к другому сайту с помощью PHP

В этом простом примере, мы будем использовать стандартную функцию PHP под названием file_get_contents().

В ответ от сервера VK, вы увидите следующую информацию:

{ - response: [ - { - id: 210700286, - first_name: "Lindsey", - last_name: "Stirling", - bdate: "21.9.1986" - } - ] }

где, мы получили Имя, Фамилию и дату рождения пользователя с ID 210700286.

Как теперь мы может с помощью PHP получить эту информацию и преобразовать ее в массив, для удобной дальнейшей работы?

С помощью языка программирования PHP и функции file_get_contents(), это сделать очень просто!

$user_id - это переменная, в которую вы записываете ID пользователя VK,

$info - в этой переменной мы сохраняем результат обращения к API сайта VK.COM

Имея массив с этой информацией, вы можете на вашем сайте, отображать интересных вам пользователей, для какой-либо цели, а также с помощью , вы можете красиво оформить вывод данной информации на вашем сайте.

Вывод

Как вы видите, с помощью PHP вы можете очень легко делать запросы к HTTP и HTTPS сайтам и мы рассмотрели лишь одну функцию языка программирования PHP с помощью которой можно получить данные из внешнего сайта.

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

Возможные атаки

Использование PHP как бинарного CGI-приложения является одним из вариантов, когда по каким-либо причинам нежелательно интегрировать PHP в веб-сервер (например Apache) в качестве модуля, либо предполагается использование таких утилит, как chroot и setuid для организации безопасного окружения во время работы скриптов. Такая установка обычно сопровождается копированием исполняемого файла PHP в директорию cgi-bin веб-сервера. CERT (организация, следящая за угрозами безопасности) CA-96.11 рекомендует не помещать какие-либо интерпретаторы в каталог cgi-bin. Даже если PHP используется как самостоятельный интерпретатор, он спроектирован так, чтобы предотвратить возможность следующих атак:

    Доступ к системным файлам: http://my.host/cgi-bin/php?/etc/passwd

    Данные, введенные в строке запроса (URL) после вопросительного знака, передаются интерпретатору как аргументы командной строки согласно CGI протоколу. Обычно интерпретаторы открывают и исполняют файл, указанный в качестве первого аргумента.

    В случае использования PHP посредством CGI-протокола он не станет интерпретировать аргументы командной строки.

    Доступ к произвольному документу на сервере: http://my.host/cgi-bin/php/secret/doc.html

    Согласно общепринятому соглашению часть пути в запрошенной странице, которая расположена после имени выполняемого модуля PHP, /secret/doc.html , используется для указания файла, который будет интерпретирован как CGI-программа Обычно, некоторые конфигурационные опции веб-сервера (например, Action для сервера Apache) используются для перенаправления документа, к примеру, для перенаправления запросов вида http://my.host/secret/script.php интерпретатору PHP. В таком случае веб-сервер вначале проверяет права доступа к директории /secret , и после этого создает перенаправленный запрос http://my.host/cgi-bin/php/secret/script.php . К сожалению, если запрос изначально задан в полном виде, проверка на наличие прав для файла /secret/script.php не выполняется, она происходит только для файла /cgi-bin/php . Таким образом, пользователь имеет возможность обратиться к /cgi-bin/php , и, как следствие, к любому защищенному документу на сервере.

    В PHP, указывая во время компиляции опцию --enable-force-cgi-redirect , а таке опции doc_root и user_dir во время выполнения скрипта, можно предотвратить подобные атаки для директорий с ограниченным доступом. Более детально приведенные опции, а также их комбинации будут рассмотрены ниже.

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

В случае, если на вашем сервере отсутствуют файлы, доступ к которым ограничен паролем либо фильтром по IP-адресам, нет никакой необходимости использовать данные опции. Если ваш веб-сервер не разрешает выполнять перенаправления либо не имеет возможности взаимодействовать с исполняемым PHP-модулем на необходимом уровне безопасности, вы можете использовать опцию --enable-force-cgi-redirect во время сборки PHP. Но при этом вы должны убедиться, что альтернативные способы вызова скрипта, такие как непосредственно вызов http://my.host/cgi-bin/php/dir/script.php либо с переадресацией http://my.host/dir/script.php , недоступны.

В веб-сервере Apache перенаправление может быть сконфигурировано при помощи директив AddHandler и Action (описано ниже).

Вариант 2: использование --enable-force-cgi-redirect

Эта опция, указываемая во время сборки PHP, предотвращает вызов скриптов непосредственно по адресу вида http://my.host/cgi-bin/php/secretdir/script.php . Вместо этого, PHP будет обрабатывать пришедший запрос только в том случае, если он был перенаправлен веб-сервером.

Обычно перенаправление в веб-сервере Apache настраивается при помощи следующих опций:

Action php-script /cgi-bin/php AddHandler php-script .php

Эта опция проверена только для веб-сервера Apache, ее работа основывается на установке в случае перенаправления нестандартной переменной REDIRECT_STATUS , находящейся в CGI-окружении. В случае, если ваш веб-сервер не предоставляет возможности однозначно идентифицировать, является ли данный запрос перенаправленным, вы не можете использовать описываемую в данном разделе опцию и должны воспользоваться любым другим методом работы с CGI-приложениями.

Вариант 3: использование опций doc_root и user_dir

Размещение динамического контента, такого как скрипты либо любые другие исполняемые файлы, в директории веб-сервера делает его потенциально опасным. В случае, если в конфигурации сервера допущена ошибка, возможна ситуация, когда скрипты не выполняются, а отображаются в браузере, как обычные HTML-документы, что может привести к утечке конфиденциальной информации (например, паролей), либо информации, являющейся интеллектуальной собственностью. Исходя из таких соображений, многие системные администраторы предпочитают использовать для хранения скриптов отдельную директорию, работая со всеми размещенными в ней файлами по CGI-интерфейсу.

В случае, если невозможно гарантировать, что запросы не перенаправляются, как было показано в предыдущем разделе, необходимо указывать переменную doc_root, которая отличается от корневой директории веб-документов.

Вы можете установить корневую директорию для PHP-скриптов, настроив параметр doc_root в конфигурационном файле , либо установив переменную окружения PHP_DOCUMENT_ROOT . В случае, если PHP используется посредством CGI, полный путь к открываемому файлу будет построен на основании значения переменной doc_root и указанного в запросе пути. Таким образом, вы можете быть уверены, что скрипты будут выполняться только внутри указанной вами директории (кроме директории user_dir , которая описана ниже).

Еще одна используемая при настройке безопасности опция - user_dir . В случае, если переменная user_dir не установлена, путь к открываемому файлу строится относительно doc_root . Запрос вида http://my.host/~user/doc.php приводит к выполнению скрипта, находящегося не в домашнем каталоге соответствующего пользователя, а находящегося в подкаталоге doc_root скрипта ~user/doc.php (да, имя директории начинается с символа ~).

Но если переменной public_php присвоено значение, например, http://my.host/~user/doc.php , тогда в приведенном выше примере будет выполнен скрипт doc.php , находящийся в домашнем каталоге пользователя, в директории public_php . Например, если домашний каталог пользователя /home/user , будет выполнен файл /home/user/public_php/doc.php .

Установка опции user_dir происходит независимо от установки doc_root , таким образом вы можете контролировать корневую директорию веб-сервера и пользовательские директории независимо друг от друга.

Вариант 4: PHP вне дерева веб-документов

Один из способов существенно повысить уровень безопасности - поместить исполняемый модуль PHP вне дерева веб-документов, например в /usr/local/bin . Единственным недостатком такого подхода является то, что первая строка каждого скрипта должна иметь вид:

#!/usr/local/bin/php

Также необходимо сделать все файлы скриптов исполняемыми. Таким образом, скрипт будет рассматриваться так же, как и любое другое CGI-приложение, написанное на Perl, sh или любом другом скриптовом языке, который использует дописывание #! в начало файла для запуска самого себя.

Что бы внутри скрипта вы могли получить корректные значения переменных PATH_INFO и PATH_TRANSLATED , PHP должен быть сконфигурирован с опцией --enable-discard-path .



<<< Назад Содержание Вперед >>>
Есть еще вопросы или что-то непонятно - добро пожаловать на наш

Похожие публикации