Большинство руководств по двухфакторной аутентификации (2FA) начинаются с этапа входа в систему. После ввода пароля запрашивается временный код, и только после его подтверждения приложение создает сессию.
Это и есть 2FA при входе. Это надежный шаблон, и для многих приложений он является правильным выбором по умолчанию.
Однако это не единственное место, где можно потребовать второй фактор.
Когда вы решаете, в какой части приложения требуется дополнительная проверка, расположение имеет значение. Вы можете потребовать ее на границе сессии, как часть входа, или на границе действия, непосредственно перед выполнением конфиденциальной операции.
Подходящий подход зависит от того, что именно вы защищаете.
2FA при входе помещает второй фактор до того, как сессия будет создана. Ступенчатая аутентификация позволяет сессии работать в обычном режиме и требует код только при выполнении действия, которое в этом нуждается.
Две разные модели угроз
Что такое 2FA при входе?
2FA при входе требует второй фактор до того, как приложение предоставит аутентифицированную сессию. Пользователь вводит пароль, получает запрос на верификацию и получает доступ только после успешного прохождения обоих факторов.
Это защищает от кражи учетных данных, поскольку одного украденного пароля уже недостаточно для входа.
Чего 2FA при входе не защищает, так это уже действующую сессию. Сессии приложения могут оставаться активными долгое время после входа, в зависимости от их конфигурации. Если злоумышленник получит валидный файл cookie сессии (например, через межсайтовый скриптинг (XSS), оставленное без присмотра общее устройство или скомпрометированное соединение), запрос на вход уже будет пройден.
С точки зрения приложения, эта сессия является аутентифицированной.
2FA при входе имеет смысл, когда большая часть приложения требует дополнительной защиты, например, панель администратора, финансовое приложение или портал здравоохранения. Если ваша модель угроз звучит как «этот человек не должен получить аутентифицированную сессию, не доказав владение вторым фактором», граница сессии — это правильное место для такого требования.
Что такое ступенчатая аутентификация?
Ступенчатая аутентификация переносит дополнительную проверку с этапа входа непосредственно перед выполнение конкретных конфиденциальных действий.
Сессия работает в обычном режиме. Пользователь входит в систему, просматривает контент и выполняет операции с низким уровнем риска. Когда он пытается сделать что-то более рискованное (например, перевести деньги, сменить API-ключ или просмотреть код восстановления), приложение требует дополнительный шаг проверки перед продолжением.
После успешной верификации приложение может записать факт недавней аутентификации на короткий период. Защищенные действия могут принимать этот статус до истечения короткого времени жизни (TTL). Для особо конфиденциальных операций вы можете сделать верификацию одноразовой.
На протяжении большей части сессии дополнительная проверка может быть излишней. Она становится важной только для нескольких действий, которые несут повышенный риск.
Ступенчатая аутентификация также может снизить последствия кражи сессии. Злоумышленник, получивший доступ к аутентифицированной сессии, все равно не сможет выполнить защищенную операцию, если не сможет пройти дополнительную проверку.
Эта защита не является абсолютной. Если злоумышленник украдет сессию во время активного окна ступенчатой аутентификации, он может унаследовать ее недавно подтвержденное состояние. Вот почему окно верификации должно быть коротким, а особо рискованные действия могут требовать проверки для каждого действия.
Вот как этот шаблон может выглядеть в Django. Миксин может требовать недавней верификации перед запуском представления на основе классов:
LoginRequiredMixin обрабатывает пользователей, которые еще не прошли аутентификацию. VerificationRequiredMixin добавляет вторую проверку только для аутентифицированных пользователей, у которых нет недавней ступенчатой верификации.
Представления, которым не нужна дополнительная защита, могут продолжать использовать LoginRequiredMixin напрямую.
Сравнительная таблица
Вопрос
2FA при входе
Ступенчатая аутентификация
Когда происходит верификация?
Во время входа, до предоставления аутентифицированного доступа
Непосредственно перед защищенным действием
Какова основная угроза?
Украденный пароль или другие скомпрометированные учетные данные для входа
Злоупотребление уже аутентифицированной сессией
Где возникает дополнительное трение?
При входе
Только при выполнении конфиденциальных действий
Помогает ли это при краже cookie сессии?
Нет, если аутентифицированная сессия уже существует
Может защитить закрытые действия, если злоумышленник не может пройти дополнительную проверку
Помогает ли это при краже паролей?
Да. Одного пароля недостаточно для входа
Не при входе как таковом, но защищенные действия все равно могут потребовать другой фактор
Лучший вариант использования
Большая часть приложения является конфиденциальной
Небольшое количество действий несет непропорционально высокий риск
Выбор правильного шаблона
Начните с вопроса, какой процент действий в вашем приложении является конфиденциальным.
Если ответ — большинство, то 2FA при входе имеет смысл. Дополнительное трение оправдано, так как большая часть приложения требует дополнительной проверки.
Если только одна или две операции несут значительный риск, ступенчатая аутентификация позволит сделать остальной пользовательский опыт более удобным. Нет причин добавлять трение при каждом входе из-за одной конфиденциальной операции.
Затем рассмотрите свою модель угроз.
Кража учетных данных — это прежде всего проблема уровня входа. Злоупотребление уже аутентифицированной сессией — это проблема уровня действия. Если вашему приложению нужна защита от обоих вариантов, вы можете объединить эти два шаблона.
2FA при входе защищает доступ к учетной записи. Ступенчатая аутентификация добавляет еще один барьер вокруг наиболее важных действий.
Одна деталь реализации особенно важна: не храните недавнюю верификацию как логическое значение, например:
Это значение может оставаться валидным до тех пор, пока существует сессия, если вы явно его не очистите.
Вместо этого сохраняйте время, когда верификация прошла успешно, и сравнивайте его с коротким TTL:
В этом примере ступенчатая верификация остается валидной в течение пяти минут, независимо от того, как долго открыта основная сессия пользователя.
Пять минут — это только пример. Выбирайте окно на основе конфиденциальности действия, пользовательского опыта и ваших требований безопасности.
Для особо рискованных операций вы также можете очищать stepup_verified_at после успешного выполнения действия, чтобы каждая защищенная операция требовала свежей верификации.
Реализация обоих методов с помощью Vonage Verify API
Оба шаблона могут использовать один и тот же поток Vonage Verify API:
- Запустите верификацию со своего бэкенда, используя номер телефона, связанный с пользователем в вашем приложении, а не номер, предоставленный клиентом.
Запустите верификацию со своего бэкенда, используя номер телефона, связанный с пользователем в вашем приложении, а не номер, предоставленный клиентом.
- Сохраните возвращенный request_id в состоянии, контролируемом сервером, например, в сессии на стороне сервера или записи в базе данных. Привяжите его к пользователю и текущей сессии. Для ступенчатой аутентификации также привяжите его к конкретной транзакции или действию, которое авторизуется.
Сохраните возвращенный request_id в состоянии, контролируемом сервером, например, в сессии на стороне сервера или записи в базе данных. Привяжите его к пользователю и текущей сессии. Для ступенчатой аутентификации также привяжите его к конкретной транзакции или действию, которое авторизуется.
- Запросите у пользователя код верификации.
Запросите у пользователя код верификации.
- Отправляйте на свой бэкенд только введенный код. Ваш бэкенд извлекает соответствующий request_id из собственного серверного состояния и проверяет код с помощью Verify API.
Отправляйте на свой бэкенд только введенный код. Ваш бэкенд извлекает соответствующий request_id из собственного серверного состояния и проверяет код с помощью Verify API.
- Предоставьте соответствующий доступ после успешной проверки, а затем очистите состояние ожидающей проверки, чтобы его нельзя было использовать повторно.
Предоставьте соответствующий доступ после успешной проверки, а затем очистите состояние ожидающей проверки, чтобы его нельзя было использовать повторно.
Verify API не нужно знать, используете ли вы эту проверку при входе в систему или перед выполнением конфиденциального действия. Ваше приложение само решает, где происходит проверка и какой доступ она предоставляет в случае успеха.
Следует помнить о двух важных правилах безопасности. Во-первых, проверка всегда должна инициироваться вашим бэкендом, а не напрямую из браузера или мобильного клиента. Это позволяет держать ваши учетные данные API и жизненный цикл проверки под контролем сервера.
Во-вторых, никогда не принимайте request_id от клиента при проверке кода подтверждения. request_id, используемый для проверки, всегда должен поступать из серверного состояния, которое ваше приложение создало при начале проверки. В противном случае клиент может потенциально отправить request_id, связанный с другой попыткой проверки, другим пользователем или другим сеансом.
Вот наглядный пример на Python с использованием SMS:
Сохраняйте возвращенный request_id в сеансе, контролируемом сервером, или в состоянии базы данных, пока проверка находится в процессе. Привязывайте его к пользователю и текущему сеансу, а для пошаговой аутентификации (step-up authentication) — к конкретной транзакции, которая авторизуется. Когда пользователь вводит свой код, извлекайте request_id из этого серверного состояния, а не принимайте его от клиента.
Если check_verification() возвращает False, не предоставляйте доступ к защищенной операции. Покажите пользователю соответствующую ошибку проверки, не раскрывая необработанные детали ошибки провайдера.
Для двухфакторной аутентификации (2FA) при входе в систему начинайте этот процесс после того, как пароль был подтвержден, но до предоставления обычного аутентифицированного доступа. Учебное пособие «Добавление двухфакторной аутентификации с помощью Node.js и Express» демонстрирует этот шаблон.
Для пошаговой аутентификации начинайте тот же процесс, когда пользователь переходит к операции, требующей дополнительной проверки. Промежуточное ПО (middleware), декоратор или специфичный для фреймворка примесь (mixin) могут проверять наличие недавней проверки и при необходимости перенаправлять на процесс проверки.
Сопутствующее учебное пособие по Django может охватить полную реализацию, включая управление сеансами, проверку перенаправлений, граничные случаи безопасности и тестирование без отправки реальных сообщений.
Какой бы шаблон вы ни использовали, в производственных приложениях также следует учитывать ограничение частоты запросов (rate limiting), защиту от межсайтовой подделки запросов (CSRF), безопасную обработку перенаправлений и привязку запроса на проверку к правильному аутентифицированному пользователю и номеру телефона.
Помимо SMS: «Тихая» аутентификация (Silent Authentication)
Приведенные выше примеры используют одноразовый пароль (OTP), доставляемый через SMS. Это требует создания видимого для пользователя кода, доставки его на устройство и просьбы к пользователю переписать его обратно в приложение.
«Тихая» аутентификация использует другой подход. Вместо того чтобы просить пользователя ввести код, она использует мобильную сеть для проверки владения номером телефона.
Это может снизить нагрузку на пользователя, поскольку не нужно ничего копировать из сообщения или уведомления.
При этом сохраняется то же архитектурное различие. Вы можете использовать проверку при входе в систему или непосредственно перед конфиденциальным действием.
Например, рабочий процесс может сначала попытаться выполнить «тихую» аутентификацию, а в случае неудачи перейти к SMS:
Если «тихая» аутентификация прошла успешно, приложение может продолжить работу, не прося пользователя вводить OTP. Если рабочий процесс переходит к SMS, применяется стандартный процесс ввода кода.
Охват и производственные требования могут варьироваться в зависимости от рынка и конфигурации. Ознакомьтесь с текущей таблицей доступности сетевых функций (Network Features Availability Table) и документацией сетевого реестра (Network Registry) перед развертыванием функции в рабочей среде.
Руководство по концепции «тихой» аутентификации более подробно описывает архитектуру и вопросы конфиденциальности.
Можно ли использовать 2FA при входе и пошаговую аутентификацию вместе?
Да.
На самом деле, эти два шаблона могут дополнять друг друга как часть более широкой стратегии многофакторной аутентификации (MFA).
Например, финансовому приложению может потребоваться 2FA при входе в систему перед предоставлением аутентифицированного сеанса, а затем снова потребоваться пошаговая аутентификация перед переводом средств.
Эти две проверки решают разные задачи в модели безопасности приложения.
Первая защищает доступ к учетной записи. Вторая защищает особо конфиденциальную операцию внутри аутентифицированного сеанса.
Использование MFA при входе не означает, что каждое конфиденциальное действие внутри полученного сеанса должно полагаться на эту раннюю проверку. Пошаговая аутентификация позволяет приложению требовать свежую дополнительную проверку, когда риск конкретного действия оправдывает это.
Vonage Verify API может поддерживать оба шаблона. Меняется лишь то, когда ваше приложение запускает проверку и какой доступ оно предоставляет после успешной проверки.
2FA при входе и пошаговая аутентификация: основные выводы
- 2FA при входе защищает границу сеанса. Используйте ее, когда получение доступа к самому приложению оправдывает использование дополнительного фактора.
2FA при входе защищает границу сеанса. Используйте ее, когда получение доступа к самому приложению оправдывает использование дополнительного фактора.
- Пошаговая аутентификация защищает отдельные действия. Используйте ее, когда небольшое количество операций несет более высокий риск, чем остальные части приложения.
Пошаговая аутентификация защищает отдельные действия. Используйте ее, когда небольшое количество операций несет более высокий риск, чем остальные части приложения.
- Они не являются взаимоисключающими. Приложения, которым нужна защита как на границе входа, так и на границе действий, могут комбинировать их.
Они не являются взаимоисключающими. Приложения, которым нужна защита как на границе входа, так и на границе действий, могут комбинировать их.
Важный вопрос проектирования заключается не просто в том, должно ли ваше приложение использовать 2FA. А в том, где именно должна находиться дополнительная проверка, исходя из того, что вы пытаетесь защитить.












