Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СИТ_Ответы_5 курс.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
577 Кб
Скачать
☆

Безопасность

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

Во-первых, опасно передавать туда-сюда пароль, его могут перехватить. Кроме того, мы зарегистрировали его как глобальную переменную сессии, значит, он сохранился в cookies на компьютере-клиенте. Это тоже плохо. И вообще, пароли и логины по-хорошему должны храниться в базе данных. Пусть информация о пользователях хранится в базе данных "test" (в таблице "users"), а мы имеем к ней доступ под логином my_user и паролем my_passwd.

Во-вторых, что делать, если кто-то написал скрипт подбора пароля для секретной страницы? В этом случае на страницу авторизации много раз должен стучаться какой-то посторонний скрипт. Поэтому нужно просто проверять, с нашего ли сайта пришел запрос на авторизацию, и если нет, то не пускать его дальше. Адрес страницы, с которой поступил запрос, можно получить с помощью глобальной переменной $_SERVER['HTTP_REFERER']). Хотя, конечно, если за взлом сайта взялись всерьез, тозначение этой переменной тоже подменят (например, с помощью того же PHP). Тем не менее проверку ее значения можно считать одним из важнейших шагов на пути к обеспечению безопасности своего сайта.

<?

session_start();

// создаем новую сессию или

// восстанавливаем текущую

$conn = mysql_connect("localhost",

"my_user","my_passwd");

// устанавливаем соединение с сервером БД

mysql_select_db("test");

// выбираем рабочую базу данных

$SERVER_ROOT = "http://localhost/~nina/tasks/sessions/";

// где находятся наши скрипты

/* с помощью регулярного выражения

^$SERVER_ROOT и функции eregi проверяем,

начинается ли адрес ссылающегося скрипта,

т.е. строка $_SERVER['HTTP_REFERER'])

со строки $SERVER_ROOT (как у нас) */

if(eregi("^$SERVER_ROOT",

$_SERVER['HTTP_REFERER'])){

// если да, то делаем почти то же, что и

// раньше, пароль регистрировать не будем

if (!isset($_POST['go'])){

echo "<form method=POST >

Login: <input type=text name=login>

Password: <input type=password name=passwd>

<input type=submit name=go value=Go>

</form>";

}else {

/* запрос к базе данных: выбираем из таблицы

users login, который совпадает с переданным

по запросу, причем пароль у него тоже должен

совпасть с введенным пользователем.

Если этого нет, то считаем, что логин и

пароль введены неверно */

$sql = "SELECT login FROM users

WHERE login='" . $_POST['login'] . "' AND passwd='" . $_POST['passwd'] . "';";

$q = mysql_query($sql,$conn); // отправляем запрос к БД

$n = mysql_num_rows($q); // число строк в ответе на запрос

if (!$n==0){

$_SESSION['user_login']=$_POST['login'];

// регистрируем переменную login

Header("Location: secret_info.php");

// перенаправляем на страницу secret_info.php

}else echo "Неверный ввод, попробуйте еще раз<br>";

}

print_r($_SESSION); // выводим все переменные сессии

}

?>

Листинг 12.6. authorize.php

Вроде бы первые две проблемы решены. Но есть еще одна. Что делать, если хакер просто допишет в строку запроса значениекакой-нибудь глобальной переменной (например, логина)? Вообще это возможно, только если register_globals=On. Просто иначе мы используем для работы с глобальными переменными массив $_SESSION и с ним такие фокусы не проходят. Все же попробуем решить и эту проблему. Для этого нужно очистить строку запроса перед тем, как сравнивать значения параметров. То есть сначала сбросим значение $user_login. Потом данную переменную нужно опять зарегистрировать, но не как новую, а как уже существующую. Для этого знак доллара при регистрации НЕ опускается. Вот что получилось:

<?php

unset($user_login); // уничтожаем переменную

session_start(); // создаем новую сессию или

// восстанавливаем текущую

session_register($user_login);

// регистрируем переменную

// как уже существующую

if (!($user_login=="pit")) // проверяем логин

Header("Location: authorize.php");

// если ошибка, то перенаправляем

// на страницу авторизации

?>

<html>

<head><title>Secret info</title></head>

... // здесь располагается

// секретная информация :)

</html>

Листинг 12.7. secret_info.php

Cookies 

PHP прозрачно поддерживает HTTP cookies. Cookies - это механизм хранения данных браузером удаленной машины для отслеживания или идентификации возвращающихся посетителей. Вы можете установить cookies при помощи функций setcookie() или setrawcookie(). Cookies являются частью HTTP-заголовка, поэтому setcookie() должна вызываться до любого вывода данных в броузер. Это то же самое ограничение, которое имеет функция header(). Вы можете использовать функции буферизации вывода, чтобы задержать вывод результатов работы скрипта до того момента, когда будет известно, понадобится ли установка cookies или других заголовков.

Любые cookies, отправленные серверу браузером клиента, будут автоматически включены в суперглобальный массив $_COOKIE, если директива variables_order содержит букву "C". Для назначения нескольких значений одной cookie, просто добавьте [] к её имени.

В зависимости от значения опции register_globals, cookies могут быть представлены обычными PHP-переменными. Однако рекомендуется не полагаться на эту возможность, так как она обычно отключена в целях безопасности. В более ранних версиях также определяется массив $HTTP_COOKIE_VARS, но только когда включена директиваtrack_vars. (Эта директива всегда включена начиная с версии PHP 4.0.3.)

Дополнительная информация, в том числе и особенности реализации браузеров, приведена в описании функцийsetcookie() и setrawcookie().