В настоящее время я планирую реализацию 2FA, чтобы пользователи должны были предоставлять код через SMS для некоторых действий, таких как вход в систему. Я также буду использовать такие инструменты, как Google Authenticator, но я не хочу, чтобы пользователи заставляли загружать приложение, поэтому мне также нужно отправлять коды по SMS (или, возможно, по электронной почте).
Мой план пока таков:
2 вопроса по этому поводу:
1) Обработка истечения срока действия кода
Моя первая идея заключалась в том, чтобы хранить код в базе данных только в хешированном виде, как пароль, но мне пришлось бы реализовать 5-минутное истечение срока действия самостоятельно. Конечно, я мог бы добавить еще один столбец с отметкой времени для проверки срока действия, но я бы предпочел что-то более безопасное.
Теперь я думаю о том, чтобы сохранить код внутри объекта утверждений веб-токена json в базе данных и установить срок действия этого токена на 5 минут. Таким образом, по истечении 5 минут синтаксический анализ веб-токена для сравнения его с кодом, отправленным пользователем, завершается ошибкой. Это позволило бы мне в случае сценария атаки просто изменить секрет веб-токенов, и все существующие коды мгновенно стали бы недействительными.
Хороший ли это подход? Или вы, ребята, видите в этом какие-то проблемы, или, может быть, есть лучшие способы справиться с этим? Или, может быть, есть библиотека для хеширования паролей с датой истечения срока действия?
2) Проверка и обработка атак грубой силы
Поскольку я хочу отправить пользователю только 6- или максимум 8-значный числовой код, мне придется реализовать какую-то защиту от атак методом грубой силы (допустим, злоумышленник знает адрес электронной почты и пароль пользователя).
Что я хочу сделать:
Это безопасный подход к проверке кодов?
И не забывайте, что вы должны заранее проверить номер SMS, чтобы злоумышленники не подделали эту проверку.
Эй, Джонс, конечно, пользователь должен подтвердить устройство при регистрации. И да, я рассматривал некоторые из этих сервисов, но у большинства из них есть недостатки. Некоторым требуется приложение, некоторые не могут отправлять токены по электронной почте, некоторые стоят дорого, и большинство из них хранят данные в США, где могут возникнуть проблемы с GDPR. Кроме того, я хочу понять, в чем заключаются проблемы при его создании, и посмотреть, правильный ли мой подход :)
Я думаю, что вы переусердствуете с безопасностью своих шестизначных кодов подтверждения, используя JWT.
Независимо от того, как вы ими управляете, вы должны сделать их недействительными по истечении срока их действия или при использовании. Хороший способ сделать это — дать каждому коду строку в таблице, включая отметку времени истечения срока действия. Затем УДАЛИТЕ строку для кода, когда пользователь представляет ее. Всякий раз, когда вы ищете эти коды, добавляйте WHERE expires > NOW()
к запросу. И регулярно DELETE строки с истекшим сроком действия.
Противостоять атакам грубой силы несложно. К тому времени, когда вы будете готовы отправить пользователю код, вы уже подтвердите его пароль, чтобы знать, кем он себя выдает. Так что просто отслеживайте попытки этого пользователя угадать код. Как вы предложили, дайте им три попытки. Затем заставьте их запросить другой код. Если они повторно запрашивают более пяти кодов в течение календарного дня, заблокируйте их до следующего календарного дня.
Эта схема, кстати, полезна для генерации всех видов одноразовых номеров. (Числа используются один раз.) Одноразовые числа пригодятся для многих целей, таких как сброс пароля по электронной почте.
Интересно, рассматривали ли вы возможность принятия одной из систем аутентификации как услуги? Onelogin, Okta, Ping, Auth0 и т. д. Вы сможете работать с ключами FIDO, SMS 2f, различными системами федерации и т. д. прямо из коробки.