Привет, Хабр! Меня зовут Денис Ульянов, я уже 12 лет в IT и последние полтора года руковожу командой Antibot в Wildberries.
До работы в WB я три года был на тёмной стороне и занимался продуктами по сбору данных из открытых источников. Нейтрально намекаю на парсеры :) Должен признать, этот опыт помогает мне отстреливать ботов на ресурсах WB.
Сегодня поделюсь, как моя команда сделала не только антибота, но и собственный парсер для атак на себя. Надеюсь, после публикации не произойдёт массовое нападение ботов!
Зачем Wildberries инвестирует в антибота
По нашим данным, до 60% трафика WB генерируют боты и парсеры. Это создаёт дополнительную паразитную нагрузку на инфраструктуру, и мы несём прямые финансовые потери. Когда же парсеры и боты автоматизируют бизнес-процессы и получают неконкурентное преимущество, мы несём репутационные потери.
Каких ботов-плохишей мы видим на радарах?
1. Рыночные парсеры. Массово парсят цены, остатки, карточки товаров, поисковую и каталожную выдачу, выдачу рекомендаций.
Зачем? Чтобы собрать максимум информации о WB как о конкуренте и узнать объём продаж, динамику роста ниш и категорий, размер скидки постоянного покупателя. В свою бытность на тёмной стороне я занимался именно этим типом парсинга, эта область мне хорошо знакома.
2. DDoS-активность. Боты нарушают работу ресурсов компаний, чтобы легитимные пользователи не смогли воспользоваться маркетплейсом.
3. Атаки на бизнес-логику. Боты хотят нам навредить переборами и массовыми попытками в чувствительных сценариях. Например, устроить перебор номеров телефонов в фиче аутентификации. Мы отправляем SMS с кодом, но вместо пользователя её получает бот. А компания вхолостую тратит деньги на отправку. Неприятно!
4. Автоматизация для получения преимущества. К примеру, селлеры используют автоматизацию, чтобы нечестным путём быстрее других забронировать слоты поставок.
Как атакуют мобильное API
Работа с парсерами на промышленной основе так или иначе приводит к взаимодействию с нашими ресурсами через бэкенд.
Слышу ваш немой вопрос: «Почему именно мобильное API?» Поделюсь двумя самыми весомыми причинами, и перейдём к атакам.
Во-первых, мобильные эндпоинты в REST API, как правило, хорошо структурированы: понятно, какие параметры нужно передавать и какой ответ возвращается. Формат JSON компактнее, легче читается и значительно удобнее для машинной обработки, чем HTML и парсинг через регулярные выражения. Мои соболезнования всем, кто этим занимался. Я понимаю, как это больно.
Во-вторых, у мобильного API есть «хвост» обновлений. Когда пласт пользователей остаётся на старых версиях приложения, мы должны сохранять обратную совместимость, чтобы не потерять эту аудиторию.
Цепочка атаки на мобильное API
Представим, что мы с вами хотим спарсить данные через мобильное API. Что будем делать?
Сначала перехватываем и анализируем трафик. Устанавливаем эмулятор Android или берём настоящий телефон, поднимаем рядом MITMproxy и заворачиваем трафик с устройства в прокси-сервер.
Далее разбираем протокол. Как взаимодействуют мобильное приложение и сервер? Какие запросы отправляются? С какими параметрами? Какие из параметров обязательные? Какая семантика у запросов?
Пишем скрипт. Достаточно простейшего скрипта, который будет автоматически отправлять запросы в бэкенд.
И наконец — масштабируем. Добавляем параллельность запросов и бот‑инфраструктуру, чтобы наш парсер стабильно работал хотя бы несколько недель без ручного вмешательства, обходил механики защиты сайта и получал антибот-токен — ключ-подтверждение, что клиент является человеком.

Теперь мы знаем, как сделать парсер, который может получить и удерживать антибот-токен. Но что это значит для нашей защиты?
Клиент всегда прав лжёт. Мы только что убедились, что не можем доверять клиенту. Его можно эмулировать, взломать и запустить в неестественном окружении. Значит, критичные проверки должны быть на сервере.
Антибот-токен нужно привязывать к устройству и сессии, чтобы повысить стоимость атаки для хакера. Ведь если клиент можно взломать, то можно и украсть антибот-токен.
Необходима серверная оценка риска и сегментация трафика. Мы должны разделять скучных (нормальных) клиентов и подозрительных, которые запущены в неизвестном окружении и, возможно, взломаны или скомпрометированы.
Копировать поведенческие признаки и возможность отзывать токены можно, но это дорого. Для команды хороших инженеров реально сделать парсер, который притворяется человеком в момент получения токена, но притворятся постоянно — дорого.
Как эволюционировал наш антибот
Архитектура антибота включает два больших компонента:
Клиентская SDK-библиотека (в нашем случае Mobile Software Development Kit) для получения и продления антибот-токена.
Сервер для валидации токена и оценки риска сессии.
Для оценки рисков мы собираем большое количество данных: результаты челленджа; сеть, из которой пришёл пользователь; поведение и ML-признаки. К последнему пункту вернусь позже. В итоге сервер даёт решение по доступу:
пропуск;
усиленная проверка;
блокировка;
отзыв токена.

Мобильное приложение Wildberries отправляет запрос на защищаемый ресурс wildberries.ru и получает отказ в доступе из-за отсутствия антибот-токена. Тогда мобильное приложение запускает флоу получения антибот-токена через Antibot SDK. SDK возвращает токен в приложение, и запрос на защищаемый ресурс повторяется — на этот раз успешно. Мы проходим проверку и получаем доступ к wildberries.ru.
Делаем Web SDK внутри WebView за одну итерацию
Когда нашей команде поставили задачу сделать Mobile SDK для приложения WB, у нас в распоряжении уже был зрелый, обкатанный Web SDK для браузера. Поэтому мы срезали углы и для быстрого старта переиспользовали его в WebView, компоненте для просмотра веб-страниц в приложении.
Мы сделали первую версию за одну итерацию и без промедления отдали ее на интеграцию продуктовой команде. Через время команда вернулась с фидбеком. Неоспоримые плюсы — это быстрый выход в прод и сбор данных для следующей итерации.
Минус — на большой аудитории в продакшене возникали проблемы, связанные с WebView (неполноценный браузер со сложностями в диагностике).
Должен признаться, если бы я вернулся в прошлое и передо мной стояла та же задача, я бы снова выбрал WebView. Плюсы перевешивают минус!
Расскажу, что именно мы запускаем в WebView.
JS-челлендж: отпечаток устройства
Наша основная механика идентификации устройства на предмет эмуляции, взлома и легитимности. Челлендж делает скоринг: собирает параметры окружения, нормализует признаки и формирует профиль устройства.
Зачем нужен этап нормализации? Если не сегрегировать данные, получится шумный отпечаток, который будет мало отличаться от случайно сгенерированной строки. Это основная механика, но у нее есть и минусы. В том числе его можно подделать. Поэтому у нас есть и другие механики.
Proof of Work (PoW)
Те, кто знаком с блокчейнами, знают об этой механике. Суть PoW (доказательства выполнения работы) в том, что для получения токена клиент должен решить некую вычислительную задачу, которая подтверждает затрату ресурсов и повышает доверие к запросу. Мы просим клиента найти определённое количество хэшей, удовлетворяющих условиям.
Сложность настраивается под разные сценарии. Надёжному клиенту можно дать задачу на поиск одного хэша, а устройству с IP-адресом в Сингапуре — поиск 50 хэшей, чтобы понять, это рядовой пользователь с VPN или боты.
Клиенту достаточно дорого решать задачу с точки зрения вычислительной мощности, но проверка на сервере проходит быстро. PoW замедляет ботов и парсеров и делает массовую оптимизацию дороже. Если устройство ограничено одной генерацией в секунду — это его лимит на майнинг токенов.
Когда мы разрабатывали механику, казалось, что это волшебная пилюля, способная решить все проблемы. Но, увы, у PoW тоже есть свои минусы.
Главное ограничение в эксплуатации — разнообразный парк устройств. Одни юзеры используют свежие флагманы с хорошей производительностью, другие — бюджетные смартфоны десятилетней давности. На слабых устройствах механика вызывает задержки в приложении, нагрев корпуса и расход батареи.
Кроме того, PoW не всемогуща: её эффект ограничен против атакующего с мощной инфраструктурой, которая на несколько порядков выше потребительского парка устройств. Поэтому мы сегментируем пользователей и используем механику точечно.
Переходим к адаптивным политикам
На запуске мы стригли всех пользователей под одну гребёнку и давали одинаковые задачи, не учитывая подозрительность, новизну устройства и прочие параметры. Конечно, это быстро вернулось бумерангом, и мы всё-таки сделали флоу прохождения антибота более динамичным, чтобы меры защиты действовали адресно.
Теперь:
Модель решений строится по уровню доверия к сессии. До скоринга мы проводим прескоринг и определяем первичный уровень доверия к устройству.
Меньше проверок для легитимных сессий. Если устройство не вызвало сомнений, упрощаем или отменяем часть проверок.
Больше челленджей и дополнительных проверок для подозрительных сессий. Усложняем получение токена для устройства с сомнительной репутацией.
Нативные платформенные проверки
Мудрость гласит: если ОС даёт тебе инструменты защиты, используй их.

Если смотреть верхнеуровнево, то, понимая логику работы одного инструмента, можно понять все три. Расскажу на примере Play Integrity API.
Приложение запрашивает проверочный токен у Play Integrity API → платформа возвращает токен с подписью → сервер проверяет валидность и привязывает результат к запросу или сессии → выбирается путь: 1) доверять без проверок; 2) выдать дополнительные задачи.
Продлеваем токен за хорошее поведение
Всё, что я описывал выше, это безопасный, но не очень приятный для клиента путь. Мы убиваем пользовательский опыт, если каждый раз заставляем юзера проходить весь флоу получения токена.
Вот что мы добавили, чтобы изменить ситуацию:
Продление токена для легитимных сессий. После выдачи токена анализируем сессию клиента на предмет аномалий. Если всё «чисто», в следующий раз флоу упрощается или токен выдаётся сразу без проверки.
Не продлеваем токен и включаем усиленную проверку для «серых» клиентов. При подозрении, что токен был скомпрометирован и передан парсеру, мы отказываем в пролонгации и просим получить токен заново.
Таким образом мы снижаем число повторных проверок и ускоряем основные сценарии в приложении.
Как мы внедрили ML в антибот-решение
Машинное обучение используется в двух этапах.
Во-первых, решение челленджей. Когда устройство приходит за токеном, информация о нём очень ограничена. Изначально мы определяли легитимность запроса посредством «if» и эвристики, а потом поняли — хватит это терпеть! Внедрили ML-модель, и теперь она на основе данных решает, доверять ли пользователю.
Во-вторых, оценка поведения после получения токена. Это более интересный и сложный этап. Модель анализирует сессию клиента и в любой момент может сделать вывод, что поведение аномально и требуется отозвать токен. Даже если токен был добыт через сервисы прохождения челленджей, он выявляется и перестаёт приниматься.

Внедрение ML позволило кратно увеличить точность распознавания ботов, снизить ложные срабатывания (когда обычный пользователь не может получить доступ к ресурсу) и дополнительно повысить стоимость атаки.
Как мы размечаем датасет
Чтобы ML хорошо работала, её нужно хорошо обучить. Мы использовали для разметки датасета два подхода.
Ручная разметка (не пренебрегайте этим на старте!). Команда Data Science вручную анализировала и кластеризовала логи, искала аномалии. После мы оценивали, похоже ли это на поведение реального пользователя или есть ли признаки компрометации.
Интеграция с продуктовыми командами, использование ретроспективных данных. Вспомним пример с перебором номеров телефонов. В момент запроса на авторизацию невозможно определить легитимность, но постфактум можно посмотреть: был ли сделан вход по данному номеру телефона, сколько было повторных проверок и т. д. Так мы размечаем ретроспективные данные и с их помощью прокачиваем ML-модель под конкретные кейсы. Логи собираются регулярно, и модель непрерывно переобучается на новые векторы атаки. Если (и когда) появится новый тип ботов, мы точно научимся с ним бороться.
RedTeam-подход: атакуем сами себя
Термин RedTeam пришёл в IT из военной среды. Красной командой называют инженеров, которые имитируют хакерскую атаку на свою инфраструктуру для проверки устойчивости. У меня был полезный опыт работы с парсерами, и я хотел, чтобы моя команда инженеров также умела ставить себя на место атакующих.
Мы разработали парсер и теперь находим и исключаем обходы до того, как это станет инцидентом. А главное — формируем привычку «думать как атакующий». Инженеры должны понимать, что на них нападают такие же люди, которые по утрам приходят на дейлики.
Что планируем внедрять в будущем?
В целом все защитные механизмы сводятся к одному — увеличению стоимости атаки для злоумышленника:
SSL Pinning: усложнение перехвата трафика и реверса. Для парсинга приложения нужно направить трафик в прокси-сервер и подменить корневой сертификат. Закрепление публичных сертификатов наших доменов препятствует этому. Если сертификат подменён (например, при атаке типа Man-in-the-Middle, «человек посередине»), приложение распознаёт ненадёжную сеть и разрывает соединение.
Интеграции с продуктами: больше контекста для точной защиты. Мы прокачали ML-модель благодаря ретроспективным данным от продуктовой команды и планируем расширять этот опыт, потому что защита не должна развиваться в вакууме.
Защищённый клиентский рантайм: сложнее модификация приложения. Мы не хотим, чтобы у злоумышленников была возможность модифицировать наше приложение для обхода защиты и майнинга токенов. Будем внедрять механики, которые этому препятствуют.
Что нужно запомнить
Во-первых, антибот в мобайле — это многоуровневая система, но ключевое решение всё равно принимает сервер.
Во-вторых, платформенная аттестация повышает доверие к устройству и сессии. Используйте инструменты безопасности, предоставляемые самой платформой.
В-третьих, ML-модель и отзыв токенов помогают выявлять автоматизацию в динамике. Отслеживайте весь жизненный цикл пользователя, а не только выдачу токена.
Задавайте вопросы в комментариях! Специалисты по парсингу, постарайтесь не сильно выдавать свой тёмный интерес :)

