X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

Открыть тему
Тема закрыта
> Защита идентификатора сессии
Alcorn
Alcorn
Topic Starter сообщение 2.9.2010, 7:12; Ответить: Alcorn
Сообщение #1


Идентификатор сессии создаётся на сервере, передаётся клиенту и по умолчанию хранится в cookies браузера, также передаётся клиентом на сервер при запросе с него определённых данных. Идентификатор может быть перехвачен злоумышленником, например, если компьютер клиента заражён вирусом (точнее любой программой-сниффером трафика).

Использование защищённого канала (ssl, https) имеет смысл только при авторизации или передаче конфиденциальной информации, в остальных случаях сайт работает по обычному http-протоколу и идентификатор сессии ничем не защищён при передаче.

Атрибут cookies - "secure" работает только во время ssl-соединения, поэтому в данном случае тоже помочь нам ничем не может. Атрибут HttpOnly запрещает чтение cookies с помощью javascript и для идентификатора сессии он выставлен по умолчанию самим asp.net. HttpOnly понимают все современные браузеры, исключение составляют только старые версии браузеров – FireFox 1.5, Safari 3 и т.д.

Защитить идентификатор можно, привязав его к уникальным данным клиента. Клиент в свою очередь может отправить на сервер всё что угодно. Единственное более-менее стабильное значение – ip-адрес (слепой спуффинг и возможность/невозможность подмены ip в современных системах – разговор для отдельной статьи).
На этом уникальные параметры клиента заканчиваются. Host (домен) – в большинстве случаев возвращает ip-адрес клиента и аналогичен remote_addr, так как мало кто выходит в интернет полазить по сайтам с работающего web-сервера.

Есть ещё параметр http_user_agent (данные браузера), в нём перечислены версия браузера и прочая служебная информация.

Существует проблема с Internet Explorer. В восьмой версии браузера есть кнопка совместимости, при нажатии на которую в рамках одной сессии посылаются другие параметры http_user_agent, в результате получаем подмену параметров и для проверяющей процедуры сей факт будет означать попытку взлома и соответственно произойдут дальнейшие препятствующие этому действия.

Также следует отметить, что на одном ip-адресе могут находиться сотни клиентов (например, локальная сеть предприятия или интернет-провайдер, предоставляющий всем клиентам единственный внешний ip-адрес). В этом случае при перехвате идентификатора сессии внутри данной сети и определении браузера методом перебора, защита не сработает и злоумышленник сможет зайти на сайт под чужими учётными данными.
В общем, идеальной защиты не будет в любом случае.
В данном примере рассмотрим защиту по обоим параметрам, ip-адресу и данным браузера клиента.
Теперь от теории перейдём к практике.

Создадим новый проект, назовём его protect. Добавим в него файл global.asax (иначе сессия может не заводиться). Создадим страницу, на которую пользователь будет переадресован в случае подмены идентификатора - /errors/cookie.html.

Далее в web.config в секцию <system.web> добавим следующий код -
[PHP]
<sessionState
mode="InProc"
stateConnectionString="tcp=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI"
sqlCommandTimeout="30"
customProvider=""
cookieless="false"
regenerateExpiredSessionId="false"
timeout="20"
cookieName="id"
sessionIDManagerType="protect.ProtectManager"
/>
[/PHP]
где cookieName="id" – задание нового имени (id) идентификатора сессии, ProtectManager – новый класс генерации идентификатора сессии.
Далее создадим модуль проверки сессии (секция <httpModules>) –
[PHP]
<add name="CheckSession" type=" protect.CheckSession"/>
[/PHP]
Этот модуль будет сверять запрос клиента с данными в идентификаторе сессии.
Теперь открываем codebehind (Default.aspx.cs), добавляем в начало неймспейсы –
[PHP]
using System.Text;
using System.Web.SessionState;
using System.Security.Cryptography;
[/PHP]
Далее реализуем модуль CheckSession –
[PHP]
public class CheckSession : IHttpModule
{
public CheckSession()
{
}

public String ModuleName
{
get { return "CheckSession"; }
}

public void Init(HttpApplication application)
{
application.BeginRequest +=
(new EventHandler(this.Application_BeginRequest));
application.EndRequest +=
(new EventHandler(this.Application_EndRequest));
}

private void Application_BeginRequest(Object source,
EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
string filePath = context.Request.FilePath;
string fileExtension = VirtualPathUtility.GetExtension(filePath);
if (fileExtension.Equals(".aspx") || fileExtension.Equals(".ashx"))
{
if (context.Request.Cookies["id"] != null)
{
if (context.Request.Cookies["id"].Value.ToString().Length >= 32)
{
string cook = context.Request.Cookies["id"].Value.Substring(0, 32);
string ip_v = context.Request.ServerVariables["REMOTE_ADDR"].Trim();
string br_v = context.Request.ServerVariables["HTTP_USER_AGENT"].Trim();
if ((ip_v != "") && (br_v != ""))
{
if (crypt.getmd5(ip_v + br_v) != cook)
{
if (context.Request.ServerVariables["URL"] != "/errors/cookie.html") context.Response.Redirect("/errors/cookie.html");
}
}
}
}
}
}

private void Application_EndRequest(Object source, EventArgs e)
{

}

public void Dispose() { }
}
[/PHP]
Немного пояснений. С помощью fileExtension.Equals ограничиваем проверку на два типа файлов – aspx и ashx, обычно в них используются переменные сессии, при этом ничего не мешает добавить и другие расширения. Далее, если идентификатор присутствует, то считываем ip, юзер-агент клиента, шифруем и сверяем с идентификатором сессии, если не совпадает, то переадресовываем на страницу ошибок, при этом сверяем url, чтобы не возникло рекурсивного вызова, если мы уже находимся на странице ошибок.

Теперь реализуем создание идентификатора сессии, в нашем классе ProtectManager перезапишем стандартные CreateSessionID() и Validate().
[PHP]
public class ProtectManager : SessionIDManager
{

public override string CreateSessionID(HttpContext context)
{
string x = Guid.NewGuid().ToString().Replace("-", "").ToLower();
string ip = context.Request.ServerVariables["REMOTE_ADDR"].Trim();
string br = context.Request.ServerVariables["HTTP_USER_AGENT"].Trim();
if ((ip != "") && (br != "")) {
string id = crypt.getmd5(ip + br) + x;
if (id.Length == 64) return id;
else return x;
}
else return x;
}

public override bool Validate(string id)
{
return true;
}
}

public class crypt
{
public static string getmd5(string input)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
}
[/PHP]
Считываем ip, юзер-агент клиента, шифруем в md5, добавляем guid (так как несколько пользователей могут иметь один и тот же ip и юзер-агент) и заводим новый идентификатор сессии. Если параметры по каким-то причинам пустые, то выдаём стандартный Guid.

Шифрование приведено для наглядности, на самом деле с ip и юзер агентом можно делать всё что угодно, хоть выдавать в открытом виде (не забываем про ограничение размера идентификатора сессии и символы-UrlEncode). Также в md5 возможны коллизии, т.е. одному и тому же хэшу может соответствовать бесконечное число входных вариантов значений. Со стороны взломщика возможен перебор значений юзер-агента + его постоянный ip до совпадения хэшей (тем более эти значения не ограничены временем жизни сессии и порой постоянны), скорость перебора md5 довольно велика и в распределённой сети может достигать миллиардов паролей в секунду и более, поэтому ограничение входных данных юзер-агента либо использование обычной соли вместо md5-шифрования порой более благоразумно.

Проверить защиту можно зайдя на сайт под разными ip-адресами и при заходе под вторым ip заменить идентификатор сессии на тот, который был при первом ip-адресе. Проверить юзер-агента можно в Internet Explorer 8, нажав кнопку совместимости (версия браузера поменяется в рамках одной сессии и соответственно вылетим на страницу ошибок). Для изменения значений cookies хорошо подходит браузер Opera, в нём можно менять значения прямо из меню.

© Автор Alcorn.
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
sht1rlitz
sht1rlitz
сообщение 19.5.2011, 14:17; Ответить: sht1rlitz
Сообщение #2


Alcorn, всё делал по статье, но почему-то cookie не создаются, хотя Page.Session.SessionID содержит всю информацию, создаваемую в CreateSessionID.
Подскажите, пожалуйста, в чём может быть загвоздка?

Замечание модератора:
Эта тема была закрыта автоматически ввиду отсутствия активности в ней на протяжении 100+ дней.
Если Вы считаете ее актуальной и хотите оставить сообщение, то воспользуйтесь кнопкой
или обратитесь к любому из модераторов.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Горячая тема (нет новых ответов) WordPress: ускорение, защита, оптимизация
35 wp01 20056 9.11.2022, 14:24
автор: wp01
Горячая тема (нет новых ответов) WordPress: ускорение, защита, оптимизация
41 wp01 9611 21.9.2020, 16:44
автор: wp01
Открытая тема (нет новых ответов) Нужна защита сайта от парсинга
Сайт парсит WpGrabber, нужна защита
18 Limonadik 4978 20.5.2020, 0:18
автор: pyaterka
Открытая тема (нет новых ответов) Удаление вирусов с сайтов, хостинга и серверов. Защита от взлома и устранение уязвимостей
0 vixan 2370 3.11.2018, 20:40
автор: vixan
Открытая тема (нет новых ответов) Тема имеет прикрепленные файлыЗащита WEB-сайтов от взлома и атак хакеров | Anti DDos
0 webitproff 1487 30.10.2017, 16:19
автор: webitproff


 



RSS Текстовая версия Сейчас: 25.4.2024, 3:12
Дизайн