На сегодняшний день идея ухода от паролей и традиционных методов аутентификации на веб-ресурсах поднимается все чаще, причем этим озаботились такие гиганты IT-индустрии, как Google, Paypal и другие члены альянса FIDO. В рамках научных исследований, проводимых сотрудниками Google, были предложены способы усовершенствования методов аутентификации, а также черновик стандарта расширения TLS, позволяющего избавиться от использования cookies.
В данной статье я расскажу о проблемах традиционных схем аутентификации, о подводных камнях при введении двухэтапной аутентификации и рассмотрю предложенный стандарт расширения TLS. Текст статьи будет полезен веб-разработчикам, планирующим встроить двухэтапную аутентификацию.
При обсуждении способов строгой аутентификации часто возникает вопрос о том, что все предложенные способы слишком сложны или неудобны для пользователя. В этом случае можно предложить два дополняющих друг друга решения:
Очевидно, что необходимость в строгой аутентификации имеют последние два типа учетных записей, причем стоит заметить, что с течением времени классы аккаунтов могут перетекать из одного в другой.
Частично этих угроз можно избежать, воспользовавшись менеджером паролей, но это требует установки отдельных программ и плохо совместимо с обилием у пользователя устройств на различных операционных системах.
Пользователям обычно нет дела до безопасности, типов их учеток и возможных угроз. Как показывает практика, любые изменения, связанные с безопасностью, воспринимаются людьми в штыки. Поэтому помимо разработки незаметных способов аутентификации также необходимо подумать о прозрачности способа перехода к новым механизмам.
Предположим теперь, пользователь может единоразово разрешить устройству доступ к своим учетным записям, таким образом делегировав своему девайсу право выполнять аутентификацию самому. В некоторой степени такая схема уже реализована в современных мобильных ОС. Требуется пересмотреть процесс кэширования аутентификационных данных, добавив описание следующих вещей:
Впоследствии, когда у пользователя будет в распоряжении несколько аутентифицированных устройств, то ему вообще не придется вводить пароли, поскольку можно будет настроить делегирование прав между отдельными устройствами. Это наводит на мысль о том, что первичная аутентификация должна выполняться с применением нескольких факторов и криптографически стойких алгоритмов.
При внедрении даже самой простой двухэтапной аутентификации необходимо продумать:
Помимо общей организации схемы доступа к учетным записям важно учесть, что многие приложения не смогут сразу перейти на новую процедуру аутентификации. В данном случае удобно реализовать аутентификацию в приложениях на базе Web-форм, как сейчас это делает Google во всех своих мобильных программах. Такой способ позволит разработчикам абстрагироваться от различных API аутентификации и рассматривать весь процесс как один черный ящик, на выходе из которого программа получит метку доступа.
Поскольку двухфакторная аутентификация должна быть наиболее прозрачной и ненавязчивой для пользователя, то очевидно, что в типовых учетных записях нельзя полностью переходить на нее. Таким образом, необходимо найти некий компромисс, который не обременит пользователя и обеспечит безопасность учетной записи. Исследования Google показали, что требование повторной аутентификации раз в месяц является слишком назойливым и в то же время не защищает от угрозы потери устройства. Золотой серединой в таком случае является требование двухфакторной аутентификации при первом заходе пользователя в систему, после чего в браузере или на устройстве записывается «супер-cookie», который авторизует конкретное устройство в дальнейшем. При этом если пользователь того хочет, он может ограничить срок жизни cookie сессией браузера.
В качестве неожиданного минуса двухэтапной аутентификации, можно выделить использование ее злоумышленниками для перехвата управлением учетной записью: после того как злоумышленник получил доступ к аккаунту с отключенной двухэтапной аутентификацией, он может настроить ее с использованием своего номера телефона, усложнив таким образом процедуру восстановления учетной записи.
Браузер (+ плагин) при этом должен предоставлять сайту два API: для регистрации новых пользователей и для аутентификации. При создании новой учетной записи сервис вызывает API регистрации, вследствие чего на устройстве генерируется новая ключевая пара, открытый ключ которой сохраняется на сервере. Впоследствии этот ключ будет использоваться при подтверждении личности пользователя следующим образом: при помощи API аутентификации сервер передает пользователю запрос, тот его подписывает и возвращает обратно. Подобная схема аутентификации реализована у нас в продуктах Рутокен Web и Рутокен Плагин.
Стоит отметить, что опыт разработчиков браузера Chrome показывает, что использование при простой аутентификации сертификатов не является целесообразным. В связи с этим Google предлагает создать расширение протокола TLS, в котором будет реализована описанная выше схема аутентификации.
Обладатель такого токена (каким-то образом полученного ранее) может получить доступ к ресурсу вне зависимости от того, кто обладает токеном и по какому каналу он передается. Таким образом злоумышленник, завладевший токеном аутентификации, может без особых проблем авторизоваться под лицом другого пользователя.
Черновик стандарта описывает расширение TLS, с помощью которого между клиентом и сервером можно создать долговременный канал, который будет сохраняться между различными HTTP-запросами и сессиями TLS, если эти подключения исходят от одного клиентского устройства.
Суть данного метода в том, что после начальной аутентификации вместо cookie на клиентском устройстве генерируется ключевая пара, открытый ключ из которой сохраняется на сервере. В дальнейшем во время установления TLS-соединения (TLS handshake) клиент доказывает серверу то, что он владеет закрытым ключом, а открытый ключ является идентификатором канала (Channel ID). Такой метод лучше использования cookies по нескольким причинам:
После получения от сервера расширенного ServerHello, клиент должен проверить стойкость выбранного алгоритма шифрования и ответить сообщением «EncryptedExtensions» после «ChangeCipherSpec» и перед «Finished». В этом сообщении указываются параметры открытого ключа и значение подписи в следующем формате:
Здесь x, y, r и s — это 32-байтовые big-endian числа. Поля x и y содержат в себе афинные координаты эллиптической кривой P-256, а поля r и s — подпись ECDSA соответствующим закрытым ключом.Общая схема TLS handshake представлена ниже на рисунке. Зеленым выделены модификации по сравнению со стандартом.
В данной статье я расскажу о проблемах традиционных схем аутентификации, о подводных камнях при введении двухэтапной аутентификации и рассмотрю предложенный стандарт расширения TLS. Текст статьи будет полезен веб-разработчикам, планирующим встроить двухэтапную аутентификацию.
При обсуждении способов строгой аутентификации часто возникает вопрос о том, что все предложенные способы слишком сложны или неудобны для пользователя. В этом случае можно предложить два дополняющих друг друга решения:
- Разделение учетных записей по их значимости
- Использование прозрачной для пользователя аутентификации
Различение учетных записей
Очевидно, что не все учетные записи требуют строгой аутентификации. Google предлагает разделить их на следующие типы:- Одноразовые учетки на сервисах, куда пользователь не планирует больше возвращаться. Таким сервисам не нужен строгий контроль аутентификации.
- Типовые учетные записи, которыми дорожит пользователь, но их утрата не повлечет материальных или репутационных потерь.
- Публичные аккаунты: Twitter или блог с большим количеством подписчиков, а также базы данных интернет-магазинов с данными кредитных карт
- Критичные аккаунты: первичные почтовые адреса или учетки он-лайн банков.
Очевидно, что необходимость в строгой аутентификации имеют последние два типа учетных записей, причем стоит заметить, что с течением времени классы аккаунтов могут перетекать из одного в другой.
Типовые угрозы
Для любой учетной записи характерны следующие банальные и не очень угрозы:- Фишинг, при грамотной маскировке которого не спасут даже двухфакторные коды подтверждения
- Повторное использование пользователями паролей (или даже одного и того же) для нескольких учетных записей
- Ввод пользователем правильного пароля не в то поле или к другой учетной записи. Эта угроза не столь очевидна, но имеет место быть: порой я сам начинал вбивать спросони пароль в форму для логина.
- Социальная инженерия, направленная на методы восстановления паролей.
- Заражение компьютера пользователя вирусами.
Частично этих угроз можно избежать, воспользовавшись менеджером паролей, но это требует установки отдельных программ и плохо совместимо с обилием у пользователя устройств на различных операционных системах.
Пользователям обычно нет дела до безопасности, типов их учеток и возможных угроз. Как показывает практика, любые изменения, связанные с безопасностью, воспринимаются людьми в штыки. Поэтому помимо разработки незаметных способов аутентификации также необходимо подумать о прозрачности способа перехода к новым механизмам.
Новые способы старой аутентификации
Делегирование аутентификации на устройства
Сейчас у людей появляется все больше новых железок, которые имеют доступ в сеть и с которых пользователи выполняют аутентификацию на различных сервисах. При этом устройства могут тем или иным образом сохранять у себя данные пользователя для последующего использования.Предположим теперь, пользователь может единоразово разрешить устройству доступ к своим учетным записям, таким образом делегировав своему девайсу право выполнять аутентификацию самому. В некоторой степени такая схема уже реализована в современных мобильных ОС. Требуется пересмотреть процесс кэширования аутентификационных данных, добавив описание следующих вещей:
- Непосредственно делегирование доступа с применением многофакторной аутентификации, если это необходимо.
- Метка должна однозначно определять устройство пользователя и быть невалидной при использовании ее с другого устройства. Это позволит серверу понимать, с какого конкретно устройства сейчас зашел пользователь, а также защитит от возможной кражи метки доступа.
- «Время жизни» метки доступа. В идеале, если метка уникальна, то доступ должен быть разрешен до тех пор, пока пользователь сам не решит ее отозвать.
- Процесс отзыва доступа в случае потери устройства. При потере устройства необходимо лишь инвалидировать метку доступа и не потребуется менять сам пароль.
- Защита самого устройства PIN-кодом и донесение необходимости этого для пользователей.
- Определение операций, требующих подтверждения со стороны пользователя (таких как смена пароля, удаление аккаунта или денежные операции
Впоследствии, когда у пользователя будет в распоряжении несколько аутентифицированных устройств, то ему вообще не придется вводить пароли, поскольку можно будет настроить делегирование прав между отдельными устройствами. Это наводит на мысль о том, что первичная аутентификация должна выполняться с применением нескольких факторов и криптографически стойких алгоритмов.
Мысли о многофакторной аутентификации
Техника двух- и болеефакторной аутентификации давно применяется в различных сферах организации информационной безопасности, а в настоящий момент многие популярные веб-сервисы включают у себя возможность многофакторной аутентификации. Например, после Google и Amazon в игру втянулись также и Twitter, Dropbox и LinkedIn. При этом большинство сервисов в качестве второго фактора используют механизм OTP. Кроме того, что данный способ не очень удобен (каждый раз надо ждать SMS, либо запустить специальное приложение, либо сгенерировать пароль на OTP-токене и затем ручками его ввести), OTP имеет ряд уязвимостей – возможность фишинга и, кроме того, необходимость хранения на сервере секрета OTP генератора в открытом виде. Горький опыт известных и не очень компаний наконец научил нас использовать стойкое хэширование паролей, после чего необходимость хранения секрета OTP в открытом виде выглядит, мягко говоря, странным. Для обеспечения безопасного хранения аутентификационных данных на сервере необходимо использовать асимметричные криптографические алгоритмы. Эти вопросы я рассмотрю дальше по тексту статьи, а пока предлагаю вниманию читателя основные сложности, возникающие при разработке системы многофакторной аутентификации.При внедрении даже самой простой двухэтапной аутентификации необходимо продумать:
- поведение приложения в случае нахождения пользователя вне сотовой сети (например, в отпуске)
- процесс восстановления пользователем своей учетной записи
- процесс смены устройства/мобильного номера и отзыва меток доступа
Помимо общей организации схемы доступа к учетным записям важно учесть, что многие приложения не смогут сразу перейти на новую процедуру аутентификации. В данном случае удобно реализовать аутентификацию в приложениях на базе Web-форм, как сейчас это делает Google во всех своих мобильных программах. Такой способ позволит разработчикам абстрагироваться от различных API аутентификации и рассматривать весь процесс как один черный ящик, на выходе из которого программа получит метку доступа.
Поскольку двухфакторная аутентификация должна быть наиболее прозрачной и ненавязчивой для пользователя, то очевидно, что в типовых учетных записях нельзя полностью переходить на нее. Таким образом, необходимо найти некий компромисс, который не обременит пользователя и обеспечит безопасность учетной записи. Исследования Google показали, что требование повторной аутентификации раз в месяц является слишком назойливым и в то же время не защищает от угрозы потери устройства. Золотой серединой в таком случае является требование двухфакторной аутентификации при первом заходе пользователя в систему, после чего в браузере или на устройстве записывается «супер-cookie», который авторизует конкретное устройство в дальнейшем. При этом если пользователь того хочет, он может ограничить срок жизни cookie сессией браузера.
В качестве неожиданного минуса двухэтапной аутентификации, можно выделить использование ее злоумышленниками для перехвата управлением учетной записью: после того как злоумышленник получил доступ к аккаунту с отключенной двухэтапной аутентификацией, он может настроить ее с использованием своего номера телефона, усложнив таким образом процедуру восстановления учетной записи.
В качестве промежуточного вывода
Итого, современные методы двухэтапной аутентификации (например, OTP over SMS) помогают защититься от угроз повторного использования паролей и утечки базы хешей паролей (ага, а иногда и паролей в открытом виде) с сервера, но все-таки показывают себя неэффективными против тщательно продуманного фишинга или таргетированной атаки, включающей в себя кражу самого телефона. Таким образом, необходимо продумать механизм, который не будет иметь уязвимостей OTP, и к тому же будет требовать от пользователя меньше действий при аутентификациии.Ближе к железу и реализации
Выше по тексту я говорил о необходимости использования криптографии с открытым ключом для защиты от фишинга и от кражи данных с сервера. При этом для хранения ключевой информации рационально использовать дополнительные устройства в виде USB-токенов. Как показывает практика, переход на такие технологии должен быть максимально простым, поэтому необходимо установить следующие требования:- Технология не должна требовать установки дополнительного ПО, выходящего за рамки браузера и его расширений
- Одного устройства должно быть достаточно для хранения данных к множеству веб-сайтов, на которых зарегистрирован пользователь
- Протоколы регистрации и аутентификации должны быть открытыми и не должны полагаться на услуги третьей стороны. Здесь очень важно отметить, что в отношения пользователя и сайта не должны вступать другие стороны, поскольку пользователь доверяет сайту (этому способствует тот же SSL)
Браузер (+ плагин) при этом должен предоставлять сайту два API: для регистрации новых пользователей и для аутентификации. При создании новой учетной записи сервис вызывает API регистрации, вследствие чего на устройстве генерируется новая ключевая пара, открытый ключ которой сохраняется на сервере. Впоследствии этот ключ будет использоваться при подтверждении личности пользователя следующим образом: при помощи API аутентификации сервер передает пользователю запрос, тот его подписывает и возвращает обратно. Подобная схема аутентификации реализована у нас в продуктах Рутокен Web и Рутокен Плагин.
Стоит отметить, что опыт разработчиков браузера Chrome показывает, что использование при простой аутентификации сертификатов не является целесообразным. В связи с этим Google предлагает создать расширение протокола TLS, в котором будет реализована описанная выше схема аутентификации.
Расширение TLS ChannelID
Данное расширение описано в черновике IETF и предлагает механизм расширения протокола TLS, позволяющее избавиться от передачи токенов аутентификации (англ., bearer token), таких как HTTP cookies или токены OAuth.Обладатель такого токена (каким-то образом полученного ранее) может получить доступ к ресурсу вне зависимости от того, кто обладает токеном и по какому каналу он передается. Таким образом злоумышленник, завладевший токеном аутентификации, может без особых проблем авторизоваться под лицом другого пользователя.
Черновик стандарта описывает расширение TLS, с помощью которого между клиентом и сервером можно создать долговременный канал, который будет сохраняться между различными HTTP-запросами и сессиями TLS, если эти подключения исходят от одного клиентского устройства.
Суть данного метода в том, что после начальной аутентификации вместо cookie на клиентском устройстве генерируется ключевая пара, открытый ключ из которой сохраняется на сервере. В дальнейшем во время установления TLS-соединения (TLS handshake) клиент доказывает серверу то, что он владеет закрытым ключом, а открытый ключ является идентификатором канала (Channel ID). Такой метод лучше использования cookies по нескольким причинам:
- Закрытый ключ никогда не покидает клиентского устройства, поэтому злоумышленник не сможет перехватить секрет из канала
- Все криптографические операции могут выполняться на отдельном устройстве, что защищает закрытый ключ от кражи непосредственно со стороны клиента
Описание процесса TLS handshake
При установлении соединения клиент может добавить расширение «channel_id(0x754F)» в сообщение ClientHello. Если сервер поддерживает это расширение, то он может сигнализировать об этом клиенту в сообщении ServerHello.После получения от сервера расширенного ServerHello, клиент должен проверить стойкость выбранного алгоритма шифрования и ответить сообщением «EncryptedExtensions» после «ChangeCipherSpec» и перед «Finished». В этом сообщении указываются параметры открытого ключа и значение подписи в следующем формате:
struct {
opaque x[32];
opaque y[32];
opaque r[32];
opaque s[32];
} ChannelIDExtension;
Здесь x, y, r и s — это 32-байтовые big-endian числа. Поля x и y содержат в себе афинные координаты эллиптической кривой P-256, а поля r и s — подпись ECDSA соответствующим закрытым ключом.Общая схема TLS handshake представлена ниже на рисунке. Зеленым выделены модификации по сравнению со стандартом.