OTP — это один элемент защиты
Одноразовый код подтверждает доступ пользователя к определённому каналу в конкретный момент. Он снижает риск повторного использования украденного пароля, но не защищает от всех атак сам по себе.
Злоумышленник может попытаться перебрать код, вызвать тысячи отправок, узнать наличие аккаунта по тексту ошибки, украсть API-ключ или обманом получить код у пользователя. Поэтому защищать нужно весь сценарий, а не только генератор шести цифр.
Короткий срок действия и одноразовость
Стандартный код Cascade состоит из 6 цифр и действует 300 секунд. После успешной проверки он не должен приниматься повторно.
При повторной отправке заранее определите политику: остаётся ли предыдущий код действительным или заменяется новым. Для пользователя это должно быть очевидно. Несколько одновременно активных кодов повышают вероятность ошибки и усложняют поддержку.
Ограничение отправок
Лимита только по IP недостаточно: много реальных пользователей могут находиться за одним адресом, а атакующий может менять IP. Обычно ограничения комбинируют:
- по телефонному номеру;
- по аккаунту или сессии;
- по IP и подсети;
- по API-ключу или компании;
- по конкретному
purpose.
После превышения лимита возвращайте предсказуемый ответ и 429, не запускайте бесконечные автоматические повторы. На интерфейсе показывайте таймер до следующей разрешённой отправки.
Защита проверки кода
Для шестизначного значения существует ограниченное число комбинаций, поэтому verify обязан иметь лимит попыток. После нескольких ошибок применяйте задержку или завершайте текущий challenge.
Номер и purpose при проверке должны совпадать со значениями при отправке. Нельзя принимать код только по его шестизначному значению без привязки к сценарию и получателю.
Завершайте вход или важное действие только после подтверждённого success: true от POST /api/otp/verify.
API-ключ только на сервере
Bearer-токен предоставляет доступ к балансу и отправке, поэтому его нельзя включать в JavaScript, мобильную сборку или публичный репозиторий. Храните ключ в менеджере секретов либо серверной переменной окружения.
Хорошая эксплуатационная практика:
- отдельные ключи для теста и продакшена;
- минимальный круг сотрудников с доступом;
- возможность быстро отозвать ключ;
- плановая ротация;
- отсутствие токена в сообщениях об ошибках и аналитике.
Если ключ оказался скомпрометирован, сначала отзовите его, затем выпустите новый и проверьте историю запросов, баланс и необычные получатели.
Безопасные ответы и логи
Фразы «пользователь не найден» и «код отправлен на существующий аккаунт» помогают перебирать зарегистрированные номера. Для восстановления доступа используйте нейтральный ответ: если данные подходят, инструкция будет отправлена.
В журналах полезны request ID, HTTP-статус, время ответа, канал и технический результат. Не записывайте:
- полный OTP;
- Bearer-токен;
- секреты webhook;
- полные персональные данные без необходимости.
Номер можно маскировать, сохраняя достаточно данных для диагностики.
Мониторинг и признаки атаки
Настройте оповещения на резкий рост отправок, большое число 422 или 429, всплеск повторных запросов, быстрое расходование баланса и новые географические или сетевые паттерны.
Полезно отдельно наблюдать долю успешной доставки и долю успешной проверки. Если сообщения доставляются, но коды почти не подтверждаются, проблема может быть в интерфейсе, злоупотреблении или неверном purpose.
Чеклист перед запуском
- API вызывается только с бэкенда.
- OTP действует 5 минут и используется один раз.
- Send и verify ограничены по нескольким признакам.
- Resend имеет задержку.
- Код связан с номером и
purpose. - Секреты и коды маскируются в логах.
- Ответы не раскрывают наличие аккаунта.
- Есть алерты на аномальную отправку и расход баланса.
- Команда знает процедуру отзыва API-ключа.
- Критичные действия получают дополнительную защиту по уровню риска.
Технические ответы и коды ошибок собраны в справочнике API, а последовательность интеграции — в пошаговой инструкции.