ProfiPHPProfiPHP
Категория: Директивы PHP

Директива Register_globals

Опишем директиву Register_globals и все подводные камни ее использования, с которыми может столкнуться вебмастер при написании программ.

Одним из самых спорных вопросов в разработке PHP стала замена в версии 4.2.0 по умолчанию параметра директивы Register_globals в положение OFF. Большинство программистов думали, что это реализация языка программирования PHP, а не простая настройка интерпретатора. Начиная с версии PHP 5.4.0 директива была удалена.

В данной статье мы разберемся, как директива Register_globals влияет на безопасность приложений, а именно неправильное использование всех ее возможностей.

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

Приведем пример, касающийся безопасности авторизации. Данный пример далек от практического использования, но он отражает суть пробелы в безопасности. Скрипт использует проверочную переменную $is_logged, в которой хранится логическое значение авторизации пользователя. Итак проверка осуществляется следующим образом:
if ( $_POST['login'] == 'login' && $_POST['pass'] == 'pass' ) {
$is_logged = true;
}

if ( $is_logged )
echo 'Привет, пользователь!';
else
echo 'Доступ запрещен!';
Если условия не выполнены, значит пользователь не авторизован. Но, авторизоваться ему поможет именно директива Register_globals. Создаем GET запрос:
script.php?is_logged=1
Таким образом, мы меняем необходимую нам переменную, и на экране появится Привет, пользователь!

Чтобы обойти эту ошибку, достаточно сначала инициализировать переменную:
$is_logged = false;
При таком решении локальная переменная перетрет глобальную по методу GET.

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

С методом GET разобрались, перейдем к методу POST.
<form action="" method="POST">
<input text="text" name="par" />
<input type="submit" value="send" />
</form>
<?php echo $par; ?>
После отправки данных в переменной $par автоматически содержаться значение, введенное в текстовое поле. Это означает, что переменная $_POST['par'] и $par будут иметь одинаковые значения.

Перейдем к Cookie:
setcookie( 'login', 'php', time( )+86400, '', $_SERVER['HTTP_HOST'] );  
echo $login; // php
Как видно из примера, переменная $login будет содержать такое же значение, как и переменная $_COOKIE['login'].

Приведем еще один аналогичный пример, в котором будем использовать сессии:
$_SESSION['username'] = 'php';
echo $username; // php
В данном примере мы используем переменную $username. Проблема заключается в том, что мы не можем быть уверены в ее значении, поскольку $username могла быть передана в GET-запросе через URL.

Обратите внимание, что Register_globals не может быть установлена ​​при исполнении функцией Ini_set. Хотя, вы можете использовать .htaccess, если ваш сервер позволяет это:
php_value register_globals Off
Также необходимо заметить, что директива Register_globals зависит от директивы Variables_order.

Добавить комментарий

Имя:
Текст комментария: