Главная > Программирование > РНР: настольная книга программиста
<< Предыдущий параграф
Следующий параграф >>
<< Предыдущий параграф Следующий параграф >>
Макеты страниц

31.4. PHP: Безопасность

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

• на компьютере пользователя устанавливают вирус типа «троянский конь», который ворует номера сессий;

• отлавливается трафик между компьютером пользователя и сервером. Конечно, есть защищенный (зашифрованный) протокол SSL, но им пользуются не все;

• незаметно подойти к компьютеру администратора и зафиксировать номер сессии.

Такие ситуации, основанные на том, что кто-то что-то у кого-то украдет, не входят в компетенцию программиста. Об этом должны заботиться администраторы и сами пользователи.

Впрочем, РНР очень часто можно «обмануть». Рассмотрим возможные точки взлома в программе авторизации пользователя.

Файл authorize.php — попытка подбора пароля с помощью скрипта.

Файл secretplace.php — попытка «обмануть» программу путем вписывания значений переменной $logged_user в адресной строке браузера, например, так:

http://www.yoursite.ru/secretplace.php?logged_user=my_host

Итак, в нашей программе явно видны две «дыры». Одна маленькая и не особо заметная, а вот вторая — просто огромная, через которую большинство хакеров и делает то, что не надо.

Как устранить «дыру» номер 1? Не будем писать тонны кода по блокировке IP-адреса и т. п., а просто проверим, откуда приходит запрос, а точнее, с какой страницы. Если это будет любая страница нашего сайта, то все нормально, а во всех остальных случаях пускать не будем. Подкорректируем файл authorize.php примера 31,6:

<?php

// открываем сессию

session_start();

// полный путь к корневой директории,

// в которой где расположены скрипты

$SERVER_ROOT = "http://localhost/test1/";

// если пользователь пришел с любой страницы нашего сайта, // то он наш.

// Переменная $HTTP_REFERER всегда доступна по умолчанию

// и содержит полный адрес ссылающейся страницы

// функция eregi() проверяет, начинается ли адрес ссылающейся

// страницы со значения в переменной $SERVER_ROOT

if (eregi("^$SERVER_ROOT", $HTTP_REFERER) ) {

    // были ли данные отправлены формой

    if($Submit) {

        // далее все, как раньше

        if ( ($user__name=="cleo" && ($user_pass=="password")) {

            $logged_user = $user_name;

            // запоминаем имя пользователя

            session_register("logged_user");

            // и переправляем его на "секретную" страницу

            header ("Location: secretplace.php");

            exit;

        }

    }

}

?>

<html>

<body>

Вы ввели неверный пароль!

</body>

</html>

Как избавиться от «дыры» номер 2? Предположим, у вас есть сайт, где каждый может зарегистрироваться, чтобы добавлять сообщения в форум. Естественно, в форуме некоторые пользователи (например, администраторы, модераторы) имеют больше возможностей, чем другие. Они, например, могут удалять сообщения других пользователей. Уровень доступа пользователя хранится в сессии, в переменной

$user_status, где $user_status = 10 соответствует полному доступу к системе. Пришедшему на сайт злоумышленнику достаточно зарегистрироваться обычным образом, а потом дописать в адресной строке браузера ?user_status=10. Вот и появился у вас на форуме новый администратор.

В принципе, любую переменную скрипта можно задать через адресную строку, просто дописав после полного адреса к скрипту вопросительный знак и название переменной с ее значением. Поправим код примера 31.7, чтобы избежать этой «дыры»:

<?php

// убираем все лишнее из адресной строки

// функция unset () "освобождает" переменную

unset($logged_user);

// открываем сессию

session_start();

// и корректируем "испорченные" переменные.

// Внимание: в этом случае переменная регистрируется не как

// новая, а как уже существующая, потому знак $ не опускается

session_register($logged_user);

if(!isset($logged_user)) {

    header ("Location:index.php");

    exit;

}

?>

<html>

<body>

Здравствуйте, <?php echo $logged user; ?>, вы на секретной странице!

</body>

</html>

<< Предыдущий параграф Следующий параграф >>
Оглавление