Прежде всего, необходимо понять архитектуру. Типичная реализация 2FA основана на временных одноразовых паролях (TOTP) через приложения типа Google Authenticator или Authy, SMS-кодах, резервных кодах или аппаратных ключах. Для тестирования важно иметь доступ к внутренним механизмам генерации и верификации кодов. В идеале, в тестовом окружении должна быть возможность программно получать сгенерированный код, минуя реальный канал доставки (SMS или почту). Например, если ваше приложение использует библиотеку для генерации TOTP, в тестах можно использовать тот же секрет (seed), что и у "пользователя", чтобы предсказать текущий код.
Рассмотрим пример модульного теста на Python для проверки логики верификации TOTP с использованием библиотеки `pyotp`:
```
import pyotp
import time
def test_totp_verification():
# Секрет, который выдается пользователю при включении 2FA (обычно в формате base32)
secret = pyotp.random_base32()
totp = pyotp.TOTP(secret)
# Генерируем текущий валидный код
current_code = totp.now()
# Симулируем проверку на стороне сервера
# Допускаем небольшое "окно" для рассинхронизации времени (обычно +-30 секунд)
assert totp.verify(current_code) == True
# Проверяем, что неверный код отклоняется
assert totp.verify('000000') == False
# Проверяем, что код, сгенерированный для прошлого периода, не работает (если окно = 0)
# Для этого нужно сгенерировать код для конкретного времени
past_time = time.time() - 31 # 31 секунда назад
past_code = totp.at(past_time)
# Верификация с окном по умолчанию (0) должна провалиться
assert totp.verify(past_code, valid_window=0) == False
# Но с окном в 1 период (30 сек) - пройти
assert totp.verify(past_code, valid_window=1) == True
```
Этот тест проверяет ядро логики. Но реальное тестирование сложнее.
Интеграционное и end-to-end тестирование — следующий этап. Здесь нужно автоматизировать сценарии с использованием реального UI. Для SMS-кодов эксперты советуют использовать тестовые шлюзы или виртуальные номера от поставщиков услуг (например, Twilio предоставляет тестовые номера, на которые можно программно получить отправленное SMS). Для TOTP можно использовать симулятор приложения-аутентификатора или, опять же, извлечь секрет из QR-кода на этапе настройки 2FA в тесте.
Критически важным является тестирование негативных сценариев и уязвимостей:
- **Лимиты попыток.** Проверьте, что после N неудачных попыток ввода кода аккаунт блокируется или требуется дополнительное действие (например, ввод резервного кода или обращение в поддержку). Напишите тест, который отправляет 5 неверных кодов подряд и проверяет, что шестая попытка даже с верным кодом отклоняется.
- **Срок действия кода.** Убедитесь, что одноразовый код работает только в течение заданного времени (обычно 30 секунд для TOTP, 2-10 минут для SMS). Тест должен симулировать ожидание и попытку использовать просроченный код.
- **Безопасность каналов.** При использовании SMS проверьте, что номер телефона в сообщении не маскируется (это может быть нарушением конфиденциальности). Для TOTP убедитесь, что секрет при настройке передается по защищенному каналу и никогда не отображается в интерфейсе после первоначальной настройки.
- **Резервные коды.** Протестируйте процесс генерации, отображения (они должны показываться только один раз!) и использования резервных кодов. Каждый код должен быть одноразовым.
- **Уязвимость к повторной передаче (replay attack).** Один и тот же код не должен приниматься дважды. Сервер должен отслеживать использованные коды в пределах их времени жизни.
Тестирование удобства использования (UX) также важно. Измерьте время, необходимое пользователю для завершения потока с 2FA. Убедитесь, что есть четкие инструкции, возможность отложить настройку 2FA (если это допустимо политикой), и что интерфейс доступен. Протестируйте сценарии, когда время жизни кода истекает прямо во время ввода — приложение должно показывать понятное сообщение.
Для автоматизации E2E-тестов с 2FA эксперты часто создают специальные тестовые утилиты или мокают сервисы. Например, в Selenium-тесте можно перехватить запрос на отправку SMS и сохранить код в переменную, доступную тесту. Или, если приложение использует почту для отправки кодов, развернуть тестовый SMTP-сервер (например, MailHog) и забирать письма через его API.
Наконец, не забывайте про нагрузочное тестирование. Генерация и верификация кодов (особенно криптографическая часть TOTP) создают дополнительную нагрузку на сервер. Убедитесь, что ваша система аутентификации выдерживает пиковые нагрузки без существенного увеличения времени отклика.
Внедрение 2FA — это компромисс между безопасностью и удобством. Тщательное тестирование помогает найти баланс, обеспечивая надежную защиту без излишних сложностей для пользователя. Используйте комбинацию модульных, интеграционных и E2E-тестов, уделяя особое внимание краевым случаям и сценариям восстановления. Только так можно быть уверенным, что ваш второй фактор действительно укрепляет, а не ослабляет систему безопасности.
Комментарии (5)