Моя демо-версия голосового ИИ пострадала от атаки по накрутке трафика на $982! Вот чему я научился

Источник: Twilio•

Моя демо-версия голосового ИИ пострадала от атаки по накрутке трафика на $982! Вот чему я научился

Узнайте, как произошла атака по накрутке голосового трафика на $982 на мою демо-версию Twilio Voice, и изучите меры по защите голосового приложения. Поймите закономерности, превентивные меры контроля и многое другое.

06 октября 2026 г.

Автор:

Редактор:

Моя демо-версия Voice AI подверглась атаке с накруткой трафика на $982! Вот что я узнал

Вы когда-нибудь считали, что демо-версия в безопасности, потому что вы никогда не публиковали ее URL? Я так и думал. Я создал голосовой ИИ-ассистент для мероприятий и конференций, оставил его работать в интернете, а позже обнаружил, что кто-то использовал его для совершения сотен несанкционированных международных звонков.

Twilio описывает голосовое мошенничество — также известное как мошенничество с разделением доходов от международных звонков (IRSF) — как злоупотребление приложением для совершения звонков на международные премиум-номера, контролируемые злоумышленником. Объем, направления, длительность и автоматизированный аудиоконтент этого инцидента соответствовали данной схеме, хотя мои логи не могли доказать, кто контролировал номера или получал доход.

Атака на мою демо-версию Voice AI длилась около четырех часов. Она обошлась примерно в $971,50 за использование Twilio и еще $10,58 за использование Google Gemini. В этом посте я покажу, как я восстановил ход событий, как злоумышленники поддерживали активность звонков и какие средства контроля должны быть у каждой публичной демо-версии голосового ИИ. Давайте разберемся!

Проект

Проект представляет собой голосовой ассистент Twilio Conversation Relay, созданный на FastAPI. Conversation Relay подключает телефонный звонок к WebSocket, обрабатывает распознавание речи и преобразование текста в речь, а также позволяет приложению отправлять расшифрованную речь звонящего в большую языковую модель (LLM).

Приложение поддерживает OpenAI, Google Gemini и Amazon Bedrock. Веб-интерфейс позволяет настроить модель, личность и голос, а затем ввести номер телефона для получения исходящего звонка.

Важная конечная точка выглядела так (предупреждение: не копируйте это!):

Скопировать код

Этот поток был удобен во время живой демонстрации: ввести номер, выбрать «Позвонить мне сейчас» и поговорить с ИИ-ассистентом. Это также означало, что любой, кто мог получить доступ к /api/call, мог попросить мой сервер совершить реальный телефонный звонок с использованием моих учетных данных Twilio.

Я никогда не рекламировал размещенный URL

Я не делился приложением в социальных сетях. Я использовал его на мероприятиях и конференциях и предполагал, что у URL небольшая аудитория.

Однако мой репозиторий на GitHub был публичным, а развертывание было подключено к публичному пользовательскому домену. URL можно было найти через репозиторий, поиск по коду, записи DNS или сертификатов, через участника мероприятия или обычное сканирование интернета. Я не могу доказать, какой путь был использован, потому что приложение не сохраняло исходный IP-адрес клиента или реферер.

Это стало одним из моих первых уроков: доступная из интернета демо-версия является публичной, даже если ее URL не рекламируется. URL — это адрес, а не контроль доступа.

Что произошло

15 августа 2026 года автоматизированный клиент начал вызывать /api/call. Трафик шел с 10:32 до 14:39 по центральному времени.

Это был не один человек, постоянно звонящий на мой номер Twilio. Каждый мошеннический звонок создавался через REST API с одного из моих номеров Twilio. Из 921 попытки 920 были направлены на один и тот же узкий израильский диапазон, начинающийся с +972229.

Схема была очень концентрированной. На 104 целевых номера было совершено от семи до десяти звонков на каждый, что составило 851 звонок. Уровень завершения составил около 98 процентов, и звонки создали почти 30 часов соединенного трафика за четырехчасовое окно.

Отслеживание доказательств с помощью Twilio CLI

Я начал с Twilio CLI и запросил записи голосовых вызовов за дату инцидента:

Скопировать код

Полезными полями были направление (direction), отправитель (from), получатель (to), статус (status), время начала (startTime), длительность (duration) и цена (price). Группировка этих записей сразу показала, что каждый звонок имел направление outbound-api, каждый звонок использовал один и тот же исходный номер, и почти каждый пункт назначения начинался с кода страны Израиля +972.

Записи об использовании разделили стоимость на основные части:

Дополнительное списание появилось 24 августа, что поначалу выглядело как второй инцидент. Записи звонков показали обратное: оно соответствовало шести звонкам, которые начались с интервалом в 21 секунду друг от друга ближе к концу инцидента 15 августа. Они длились от 9 минут 21 секунды до 10 минут 1 секунды, в среднем около 9 минут 48 секунд. Такая плотная кластеризация указывала на скоординированную автоматизацию, а не на случайное поведение звонящего.

Это хорошее напоминание о необходимости сопоставлять записи об использовании с базовыми логами ресурсов, а не полагаться только на дату выставления счета.

Сопоставление звонков с логами Azure

Приложение работало в Azure Container Apps и отправляло логи консоли в Log Analytics. Я запросил окно инцидента на наличие запросов к конечной точке вызова:

Скопировать код

Результатом стало соединение, которое мне было нужно: 1008 POST-запросов, 921 успешный ответ и 87 сбоев. 921 успешный запрос приложения точно совпал с 921 записью звонков Twilio.

Инспектор запросов Twilio предоставил еще одно звено в цепи. Типичный мошеннический звонок обращался к конечной точке /twiml размещенного приложения и подключался к его WebSocket ConversationRelay. Это исключило стороннее приложение Twilio в той же учетной записи.

К сожалению, логи приложения содержали внутренний адрес входящего трафика Azure, а не публичный IP злоумышленника. Исходное значение X-Forwarded-For не было записано, и перед Container Apps не было прокси-сервера, сохраняющего логи доступа. Я мог идентифицировать скомпрометированную конечную точку, но не человека или машину, стоящую за запросами.

Это была накрутка трафика или мошенническая кампания?

Следующим вопросом было, пытались ли звонки обмануть реальных людей или были разработаны для накрутки трафика.

Руководство Twilio для разработчиков по борьбе с мошенничеством описывает накрутку голосового трафика как исходящие звонки, направленные на направления, контролируемые мошенником. На такие звонки могут отвечать автоматизированные записи или тишина, чтобы поддерживать соединение и генерировать доход за минуту.

Схема звонков уже соответствовала этому описанию: один международный диапазон, повторяющиеся звонки на одни и те же номера, очень высокий уровень завершения и устойчивый автоматизированный трафик.

Логи преобразования речи в текст сделали намерение еще более ясным. Из 8363 расшифрованных подсказок было всего 541 уникальная строка. Удаленная сторона сотни раз воспроизводила одни и те же подсказки для продления разговора:

Скопировать код

Другие звонки воспроизводили несвязанные предварительно записанные аудиозаписи, включая обсуждение предсказания Нибиру 2012 года и религиозные комментарии. Некоторые записи неоднократно говорили: «Спасибо, что позвонили на наши номера. Желаем вам счастливого трафика».

Я также искал в 7791 ответе ассистента общие темы вишинга. Не было повторяющихся упоминаний призов, ордеров, присяжных, подарочных карт, биткоинов, банковских переводов или языка «отправьте деньги». Доказательства убедительно подтверждали международный искусственно завышенный трафик (AIT), а не мошенническую кампанию, направленную на потребителей.

Имеющиеся доказательства не позволили установить, кто в конечном итоге получил финансовую выгоду, поэтому я не могу окончательно приписать мотив или владение. Что я могу сказать, так это то, что поведение соответствовало автоматизированной накрутке трафика.

Поставщик ИИ также пострадал

В каждой активной сессии использовалась модель Google Gemini 2.5 Flash. Журналы Azure показали 614 сессий Conversation Relay, 8363 обработанных промпта, 7791 отправленный ответ и отсутствие изменений в конфигурации модели во время инцидента.

Google AI Studio показала один скачок расходов примерно в дату атаки на общую сумму 10,58 доллара. Это небольшая сумма по сравнению со стоимостью голосовой связи, но она продемонстрировала важный момент: скомпрометированный голосовой рабочий процесс может одновременно создавать расходы у нескольких провайдеров.

Для голосового ИИ-приложения ваша финансовая граница включает телефонию, речевые сервисы, LLM, инфраструктуру, логирование и любые последующие инструменты, которые может вызывать модель.

Почему проверки подписи Twilio было недостаточно

Twilio подписывает входящие запросы вебхуков и WebSocket с помощью X-Twilio-Signature. Приложения должны проверять эту подпись с помощью серверного SDK, как описано в документации по безопасности вебхуков Twilio.

Проверка подписи необходима, но она не остановила бы этот инцидент. Поток запросов выглядел так:

Скопировать код

Злым умыслам не нужно было выдавать себя за Twilio — мое приложение выполняло привилегированную работу от имени злоумышленника. Полученные обратные вызовы Twilio были подлинными и прошли бы проверку подписи.

Проверка подписи должна выполняться на /twiml и при рукопожатии ConversationRelay WebSocket. Аутентификация и авторизация должны выполняться на /api/call и /api/config. Они решают разные задачи, и этому приложению требовалось и то, и другое.

Первые средства контроля, которые я внедрил

Моим первым изменением стало жесткое ограничение максимальной продолжительности вызова в две минуты:

Скопировать код

Приложение также планирует серверный таймер, который завершает вызов через API Twilio. time_limit в Twilio и таймер приложения предоставляют две возможности остановить неожиданно долгий вызов.

Затем я добавил комбинированный лимит на входящие и исходящие вызовы в день для каждого удаленного номера:

Скопировать код

Перед созданием исходящего вызова приложение проверяет как историю вызовов Twilio, так и локальный набор недавно созданных Call SID. Локальный набор устраняет задержку между созданием вызова и его появлением в API списков Twilio, а асинхронная блокировка предотвращает одновременные запросы, которые могут обойти проверку. Та же квота применяется, когда /twiml обрабатывает входящий вызов.

Использование истории Twilio означает, что перезапуск приложения не сбрасывает дневной счетчик. Как только лимит достигнут, исходящие запросы получают HTTP 429, входящие вызовы отклоняются, а существующие исходящие потоки разрываются.

Эти средства контроля снижают риски, но не являются полным решением. Злоумышленник перебирал 156 номеров назначения. Лимит в пять вызовов для каждого пункта назначения все равно позволил бы совершить сотни вызовов без глобального ограничения.

Более безопасная база для демонстраций голосового ИИ

Если бы я развертывал эту демо-версию с нуля сегодня, я бы использовал несколько независимых средств контроля.

Требуйте доступ перед действием

Защищайте каждую конечную точку, которая может тратить деньги или изменять поведение во время выполнения. /api/call требует аутентификации и авторизации, а /api/config не должен быть доступен для записи анонимным посетителям. Для демонстраций на мероприятиях используйте временный код доступа, аутентифицированную сессию оператора или список разрешенных направлений. Держите исходящие вызовы отключенными по умолчанию и включайте их только на время демонстрации.

Ограничивайте по нескольким параметрам

Ограничение скорости на номер полезно, но добавьте лимиты на IP, на пользователя, глобальные лимиты на одновременные вызовы, глобальные дневные лимиты и дневные расходы. Думайте об этих лимитах как о предохранителях: если какой-либо параметр ведет себя неожиданно, приложение перестает создавать вызовы.

Ограничивайте направления

Включайте только те страны и диапазоны номеров, которые требуются для демо. Twilio рекомендует ограничивать приложения для проверки концепции только необходимыми направлениями с низким уровнем риска с помощью географических разрешений на голосовой набор. Демонстрация для мероприятия в США, которая звонит только проверенным участникам из США, не имеет причин разрешать произвольные международные звонки.

Проверяйте запросы Twilio

Проверяйте X-Twilio-Signature на /twiml и при рукопожатии Conversation Relay WebSocket. Это предотвращает ситуацию, когда прямые клиенты притворяются Twilio, подделывают параметры вызова или открывают неавторизованные сессии модели. Это дополняет аутентификацию приложения, а не заменяет ее.

Добавьте финансовые барьеры

Создайте триггеры использования Twilio для вызовов, минут и цены, а также настройте бюджеты или квоты у каждого ИИ-провайдера. Оповещение также должно запускать автоматический ответ, например, отключение исходящих вызовов при превышении порога. Одни только оповещения могут прийти уже после того, как расходы начали накапливаться.

Изолируйте демо

Используйте отдельный субаккаунт Twilio, ключ API, проект ИИ-провайдера и инфраструктурную среду для каждой публичной демонстрации. Предоставляйте только те разрешения и направления, которые необходимы. Когда мероприятие заканчивается, отзывайте ключи или отключайте среду.

Защищайте учетные данные

Храните учетные данные Twilio, ИИ-провайдера и облака в менеджере секретов. Если используете GitHub для размещения кода, включите сканирование секретов GitHub и защиту от пуша. Используйте ограниченные ключи API и принцип наименьших привилегий. Ротируйте или отзывайте демо-учетные данные после мероприятий.

И никогда не коммитьте файлы .env.

Логируйте для расследований, не логируя все подряд

Записывайте доверенный перенаправленный IP, аутентифицированного пользователя, конечную точку, Call SID, хешированный пункт назначения, статус, длительность и выбор модели. Храните эти структурированные события достаточно долго, чтобы расследовать инцидент.

Полные логи разговоров были ценны во время этого расследования, но они могут содержать конфиденциальную речь. В продакшене избегайте логирования необработанных промптов и ответов по умолчанию. Используйте короткие сроки хранения, контроль доступа и редактуру, когда логирование контента необходимо.

Что этот инцидент изменил для меня

Я люблю создавать демо, потому что они делают API осязаемым. Вы нажимаете кнопку, ваш телефон звонит, и вы внезапно разговариваете с ИИ-моделью — эта немедленная обратная связь делает инструменты разработчика захватывающими!

Этот инцидент помог изменить мое представление о границах вокруг этих демо. Код может быть экспериментальным, но учетные данные, телефонная сеть, облачная инфраструктура и биллинговые аккаунты — реальны. Если публичная конечная точка может инициировать платное действие, она заслуживает такого же моделирования угроз, как и продакшн-конечная точка.

Обучение на публике также означает обмен неудачами, а не только отполированными запусками. Я надеюсь, что эта история поможет вам пересмотреть свои обратные вызовы, номеронабиратели, формы OTP, ИИ-агентов и демо для конференций, прежде чем бот сделает это за вас! Если вы хотите изучить другую реализацию голосового ИИ, ознакомьтесь с моей демо Twilio Agent Connect с AWS Bedrock AgentCore. Она сочетает Twilio ConversationRelay с агентом, размещенным на AWS, и прокси-сервером вебхуков Lambda, а инфраструктура и шаги развертывания включены в репозиторий.

Заключение

Эта демо голосового ИИ превратилась в практический урок по накачке трафика, наблюдаемости и эшелонированной защите. Логи Twilio выявили закономерность международных вызовов, логи Azure доказали, какая конечная точка была скомпрометирована, а транскрипты речи выявили автоматизированный скрипт, созданный для поддержания соединения.

Ограничения по длительности и количеству номеров — это хорошее начало, но именно аутентификация, глобальные автоматические выключатели, географические ограничения, проверка подписи, бюджеты провайдеров и изоляция демо-версий делают систему устойчивой. Продолжайте создавать, продолжайте учиться и относитесь к любой доступной из интернета демо-версии так, будто кто-то, кого вы не приглашали, в конечном итоге ее найдет — потому что рано или поздно это произойдет.

Хотите получать актуальную информацию о тенденциях в сфере мошенничества, которые наблюдает Twilio? Ознакомьтесь с нашими ежеквартальными обновлениями по вопросам мошенничества, чтобы узнать больше.

Ришаб Кумар — евангелист для разработчиков в Twilio и энтузиаст облачных технологий. Свяжитесь с Ришабом в Twitter @rishabincloud и следите за его приключениями в области облачных технологий, DevOps и DevRel на rishabkumar.com .

О чём эта статья