Аргерих Л. О языке РНР. Часть 5. Страница 84


Из этого следует извлечь несколько уроков. Функция register_globals удоб­на и ускоряет программирование на РНР, но она небезопасна. Справиться с проблемой можно двумя способами:

♦ Отключить register_globals и пользоваться ассоциативными массивами $HTTP_*_VARS

♦ Обеспечить явную инициализацию всех переменных. Для нашего сцена­рия проблема решается включением в его начале строки $ logged i г = 0;, Недостаток инициализации каждой переменной в том, что при наличии кода из тысяч строк трудно гарантировать, что любое прохождение кода неуязвимо для атаки.

Нельзя переоценить важность применения массивов $HTTP_*_VARS вместо ге- gister_globals. Почти все атаки на сценарии РНР основываются на этой функции.

Начиная с РНР 4,2.0 команда разработчиков РНР приняла решение отключать эту функцию по умолчанию. Она остается доступной, но требует явного включения через файл php. ini.

О чем надо помнить, программируя на РНР, так это о том, чтобы отключить register_globals или обеспечить инициализацию всех переменных. Это дела­ет невозможными 90% всех атак.

Шаун Клоуз (Shaun Clowes) выделяет восемь различных видов атак, которые возможны, главным образом, из-за отсутствия инициализации и включения register_globals. Его белая книга «A Study in Scarlet - Exploiting Common Vul­ nerabilities in PHP Applications» есть на http://www.securereality.com.au/">http://www.securereality.com.au/ studyinscarlet.txt. Прочтите этот документ и задайте себе вопрос: сколько атак осталось бы возможными при выключенной register_globals? Ответ будет - ни одной.

Из-за недовольства необходимостью постоянно вводить $HTTP_P0ST_VARS раз­работчики РНР добавили псевдонимы для вех этих массивов - $_POST, $_GET, $_С00К1Еи $_ENV.

Очень легко перенести имеющиеся сценарии в среду, в которой register_glo- bals отключена, если явно зарегистрировать переменные, которые жела­тельно было зарегистрировать в глобальном пространстве имен. Например, в начало приведенного сценария надо добавить две строки:

$user = $_GET["user"]; $pass = $_GET["pass"];

Доверие к данным, вводимым пользователем

Другая распространенная ошибка - доверие к данным, вводимым пользова­телем. Вот довольно абсурдный пример:

<?php

if (isset($_GET["filetype"]))

exec( ",1s *.". $_GET[ "filetype" ]);

?>\

<body> <form method="get">

Search Directory for files of type: cinput type="text" name="filetype"> <input type="submit"> </form>