Двухфакторная авторизация по смс с барышнями и преферансом

Это рассказ про то, как для элементарного поля «введите код из смс» был построен велосипед с большим числом колёс неправильной формы. Приглашаю покритиковать универсальный модуль для двухфакторной авторизации.image

ПроблемаОднажды шеф попросил прикрутить к одному веб-сервису двухфакторную авторизацию. Пользователи уже давно входили по логину и паролю, а требовалось добавить подтверждение входа по смс. Подходящего готового решения в сети не нашлось, значит нужно делать самому. Да что тут делать-то, к вечеру всё будет! В общем, через три дня форма входа запрашивала номер мобильника и требовала ввести код из смс. Смс отправлялось через API одного из многочисленных смс-провайдеров за небольшие деньги.Вскоре решение было с помощью напильника перенесено на еще одну веб-админку на PHP. Через пару недель стало приходить много жалоб, что смски приходят с огромной задержкой, или не приходят совсем. Решили поменять шлюз отправки сообщений. Естественно, на обоих сервисах. Помогло не на долго, стало ясно что нужен резервный канал отправки. Так потратился ещё день-два. Далее через несколько месяцев на одном из сервисов злоумышленник скликал все деньги, которые были на счету у смс-провайдера. Пришлось ещё немного усложнить систему, и продублировать решение. Следующий сбой произошел, когда мобильные операторы переходили на новые правила для рассылок смс касательно содержания поля отправитель. В тоже время случайно обнаружилось, что у двух коллег в офисе не приходит смс для входа в банк-клиенты двух разных весьма крупных банков. Тогда стало ясно — хватит это терпеть, миру нужно универсальное решение для двухфакторной авторизации по смс!

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

image

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

Запрос от сайта к серверу авторизации идёт через браузер пользователя. Сервер сайта полностью абстрагирован от понятия смс и получает только одобрение от сервера авторизации. Сервер сайта выставляет куку с запросом на подтверждение по смс. JavaScript обнаруживает эту куку и инициирует взаимодействие с сервером отправки смс по AJAX. Сообщение об успешной проверке смс передается на сервер сайта также с помощью куки. Сайт производит авторизацию, когда ему переданы правильные логин, пароль и кука с подтверждением от сервера авторизации по смс.

Безопасность Запросы между серверами сайта и авторизации проходят через браузер пользователя. Чтобы он не смог их подменять, будем каждый запрос подписывать ключом, который знают оба сервера, но не знает браузер. Также назначим срок годности пакета данных, передаваемого между серверами. После таких ограничений, максимум что можно сделать после полной компрометации браузера — перехватить логин, пароль и одобрение от сервера авторизации. Это позволит одновременно войти на атакуемый сайт с еще одного компьютера. Предполагается, что злоумышленник в этом случае поступит проще, и просто заберёт сессию! Если скомпрометирован сервер авторизации, то злоумышленник узнает телефоны пользователей и получит возможность подделывать ответы от сервера авторизации. Однако, для доступа к учетным записям на сайте этого мало, нужно знать логины и пароли, которых на сервере авторизации нет.

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

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

Что сделано Собственно посмотреть и скачать можно на magiclogin.ru.image

В настоящий момент модуль двухфакторной авторизации по смс доведен до работоспособного состояния и работает на нескольких сайтах.

Написан PHP-класс для установки на сервер сайта, есть подробная инструкция по установке. Интерфейс «Введите код из смс» реализован в виде модального окна, которое генерируется из JavaScript. Поддержка IE 7+, современных Chrome, Firefox, Opera, Safari, Android. Пользователь может изменить номер телефона. Можно разрешить пользователям отказываться от двухфакторной авторизации. Есть админка для просмотра статистики и оплаты. Ближайшие планы Cделать плагины для основных движков на PHP. Очень хочется сделать класс для сервера сайта на C#, Java, Python. Сделать конструктор цветовой схемы модального окна. Если у Вас есть пожелания по функциональности, пожалуйста, отпишитесь в комментариях.

© Habrahabr.ru