SMS pumping: как распознать накрутку и защитить бюджет

SMS pumping — это искусственная генерация большого числа сообщений, обычно через публичную форму OTP, на номера или направления, от которых атакующий получает выгоду. Для бизнеса результат выглядит как резкий рост расходов, низкая доля завершённых регистраций и тысячи формально успешных API-запросов.
Обычная защита от спама исходящей рассылки здесь недостаточна: злоумышленник сам вызывает законный пользовательский сценарий. Нужны лимиты до отправки, поведенческий анализ, бюджеты и автоматическая остановка аномального потока.
Как выглядит атака
Публичная страница регистрации принимает номер и вызывает отправку кода. Скрипт перебирает номера определённого диапазона или страны, меняет IP и устройство, поэтому единичные запросы выглядят допустимо. Пользователи не завершают вход, но каждое SMS тарифицируется.
Признаки могут быть разными:
- объём OTP резко вырос без роста активных пользователей;
- доля успешных проверок кода упала;
- появились новые дорогие направления или операторы;
- много запросов идёт на последовательные номера;
- одинаковые характеристики устройства встречаются у разных аккаунтов;
- повторные коды запрашиваются сразу после минимальной паузы;
- расход растёт быстрее установленного бизнес-показателя.
Ни один признак не доказывает атаку отдельно. Их объединяют в риск-оценку и сравнивают с нормальной линией продукта.
Защита до SMS API
Самый дешёвый запрос — тот, который не дошёл до провайдера. Перед отправкой проверяйте серверную сессию, допустимость сценария, лимиты на номер, аккаунт, устройство, IP/сеть и направление. Правила защиты OTP от перебора закрывают значительную часть этого контура.
Добавьте ограничения по общему объёму:
- число SMS на страну или оператора за окно;
- бюджет сценария за час и день;
- доля новых направлений;
- лимит одного клиентского приложения или партнёра;
- максимальная скорость роста относительно базовой линии.
Локальный лимит на один IP легко обходится распределённой сетью. Глобальный лимит без сегментации, наоборот, позволяет атакующему заблокировать всех. Нужна иерархия ограничений и управляемая деградация.
Паузы и доказательство намерения
Повторная отправка не должна быть доступна мгновенно. Сервер возвращает время следующей допустимой попытки и увеличивает паузу при подозрительном поведении. Клиентский таймер только отображает правило, а не реализует его.
Перед дорогим направлением можно потребовать дополнительный сигнал: успешное прохождение bot challenge, подтверждённую сессию, заполнение предыдущего шага, риск-проверку устройства. Это не должно превращать обычную регистрацию в полосу препятствий, поэтому усиление включают адаптивно.
Не используйте доставку SMS как единственный способ доказать, что запрос сделал человек: сам факт отправки уже создаёт расход.
Маршруты, страны и allowlist
Если продукт работает только с российскими номерами, запрет международных направлений должен действовать на вашей стороне и у провайдера. Если международная аудитория нужна, включайте страны осознанно, с отдельными лимитами и ценовыми порогами.
Список разрешённых направлений безопаснее бесконечного списка запрещённых. Новая страна или дорогой диапазон не должны автоматически получать полный лимит. Изменения конфигурации проходят согласование и попадают в аудит.
MNP означает, что код номера не всегда точно определяет текущего оператора. Для маршрутизации и анализа используйте актуальные данные, а не только префикс; об этом рассказано в материале про MNP и HLR.
Бюджетные предохранители
Для каждого сценария задайте мягкий и жёсткий порог расходов. Мягкий создаёт алерт и снижает скорость, жёсткий останавливает или переводит поток в защищённый режим. Порог должен учитывать сезонные пики, но не быть настолько большим, чтобы предупреждение пришло после существенного ущерба.
Считайте не только рубли за день, но и стоимость успешного действия: подтверждённой регистрации, входа или операции. Если расход растёт, а подтверждений нет, это сильнее обычного роста аудитории.
Порог связывают с фактическим тарифом и заранее понимают, что входит в стоимость SMS-рассылки, чтобы аномалия не скрылась внутри общей суммы.
Автоматическая реакция
При высоком риске возможны разные действия:
- увеличить паузу повторной выдачи;
- потребовать дополнительную проверку;
- временно остановить конкретное направление;
- ограничить новый трафик, сохранив действующие аккаунты;
- перевести запросы на ручной разбор;
- отозвать скомпрометированный ключ или интеграцию партнёра.
Полная остановка всех OTP — крайняя мера. Она защищает бюджет, но блокирует пользователей. Лучше заранее определить уровни деградации и сообщение интерфейса, чтобы клиент понимал, когда повторить попытку.
Логи и расследование
В логах SMS-отправок связывайте выдачу кода с сессией, устройством, риск-решением, направлением, стоимостью и результатом проверки — без хранения самого OTP. Сохраняйте версию правила, которое разрешило или остановило запрос.
Для расследования важны временная шкала, диапазоны номеров, партнёрский источник, изменения конфигурации и расходы. Доступ к этим данным ограничивают: номер телефона остаётся персональными данными даже в контексте атаки.
Работа с провайдером
Заранее узнайте, какие лимиты и блокировки доступны на стороне SMS-платформы: страны, скорость, бюджет, уведомления, отдельные ключи и аккаунты. Свои ограничения должны срабатывать раньше, но второй слой снижает ущерб при ошибке приложения или утечке ключа.
Во время инцидента передавайте провайдеру конкретный интервал, направления, message ID и объёмы. Просьба «у нас большой расход» без технических данных замедляет блокировку.
Тестирование защиты
В тестовой среде создайте нормальный поток, затем резкий всплеск по одному номеру, множеству последовательных номеров, новому направлению и нескольким сетевым источникам. Проверьте, что защита различает сценарии, а бюджетный стоп срабатывает до внешнего API.
Нагрузочный тест не должен сам стать платной атакой. Используйте заглушку провайдера и отдельный разрешённый реальный canary, как описано в статье про нагрузочное тестирование SMS.
Разделение продуктового роста и атаки
Резкий рост после рекламной кампании может быть законным. Чтобы автоматическая защита не остановила реальных клиентов, перед крупным запуском зарегистрируйте ожидаемый объём, географию и время. Это не отключает лимиты, а временно задаёт новую проверяемую базовую линию.
Сравнивайте воронку: просмотр формы, запрос OTP, успешная доставка, проверка кода, завершённая регистрация. При продуктовом росте обычно увеличиваются соседние этапы. При pumping резко растёт платная отправка, а дальнейшие действия почти не меняются.
Отдельные ключи для источников
Мобильное приложение, сайт и партнёрская интеграция должны использовать разные технические идентификаторы и лимиты. Тогда компрометацию одного источника можно остановить без полного отключения OTP. Общий ключ для всей компании превращает локальную проблему в общую.
Права ключа ограничивают допустимыми сценариями и направлениями. Партнёр не должен иметь возможность отправлять произвольный текст или менять Sender ID. Неиспользуемые ключи отзываются, а ротация не создаёт период, когда оба секрета бесконтрольно активны.
Финансовый разбор инцидента
После остановки сопоставьте запросы приложения, принятые сообщения провайдера, DLR и тарификацию. Разделите предотвращённые, фактически отправленные и спорные операции. Зафиксируйте, какой порог сработал первым и сколько времени прошло до реакции.
Изменения должны закрыть конкретную причину: лимит направления, новая проверка сессии, отдельный ключ или более ранний бюджетный алерт. Просто увеличить общий порог после ложного срабатывания — значит сделать следующую атаку дороже.
Итог
SMS pumping обнаруживается на разрыве между объёмом отправок и реальными пользовательскими действиями. Защита сочетает многомерные лимиты, allowlist направлений, паузы, риск-сигналы, бюджетные предохранители и быстрый режим деградации. Чем раньше решение принимается до SMS API, тем меньше финансовый ущерб и влияние на законных пользователей.