С появлением прогрессивных технологий защиты от автоматизированных запросов на веб-сайтах задача распознавания ботов становится всё более значимой. Одним из таких решений является BotID от компании Vercel — система, позиционирующая себя как невидимая капча, позволяющая выявлять сложных ботов без визуальных тестов или участия пользователя. В данном исследовании предлагаем глубоко погрузиться в технологию BotID, изучить её архитектуру, выявить способы шифрования и обфускации, а также рассмотреть возможности обхода нескольких встроенных проверок. Компания Vercel, известная благодаря своей платформе для хостинга сайтов и фреймворку Next.js, предложила BotID как ответ на растущую проблему атак с использованием автоматизированных скриптов и ботов.
Цель системы — нейтрализовать угрозы для бизнеса и защитить ресурсы без ухудшения пользовательского опыта. BotID реализуется в двух режимах — Basic и Deep Analysis. Первый предлагается бесплатно и собирает достаточно минимальный набор данных, второй — платный сервис, в основе которого лежит интеграция с решениями Kasada, обеспечивающими более углубленный анализ. Внедрение BotID в проекты на базе Next.js достаточно просто: после установки пакета botid разработчик может включить проверку запросов и в случае подозрения прервать взаимодействие с ботом.
Это удобно для контроля доступа в API и сохранения ресурсов. Одним из ключевых элементов системы является загрузка ультраобфусцированного файла c.js, содержащего логику сбора сигналов браузера и криптографических операций. Интерпретация и расшифровка этого скрипта стала вызовом, так как использованы современные методы JavaScript обфускации — случайные индексы, маскированные вызовы встроенных функций, преобразование названий методом Base64 с применением RC4, а также собственные заглушки, усложняющие анализ статическими средствами. Для снятия обфускации применялась связка инструментов Babel и node vm.
Сначала в абстрактном синтаксическом дереве (AST) выявлялись функции с массивами строковых констант, применялся поиск «shuffle»-функций — циклов с бесконечным выполнением, перемешивающих элементы массива, и декодирующих процедур. Затем изолированные куски кода импортировались в отдельную VM для динамического выполнения и последующей подстановки расшифрованных значений в исходный скрипт. Благодаря этому удалось преобразовать зачастую зашифрованные вызовы в читаемые методы, например, TextEncoder.encode или crypto.subtle.
importKey. Важной частью является асинхронная функция X, которая использует WebCrypto API для генерации случайных значений (salt и IV), импортирования ключей PBKDF2, а затем шифрования данных с использованием AES-GCM. Заключительный результат кодируется в base64 и формирует полезную нагрузку, отправляемую серверу для определения «человечности» посетителя. Использование сильных криптографических инструментов говорит о серьёзном подходе к защите данных и исключению возможности простых подделок сигнала. Помимо криптографии, скрипт вооружён множеством проверок, направленных на выявление признаков использования автоматизированных или безголовых браузеров.
Среди них — анализ объектов JavaScript на предмет характерных утечек (например, свойства window.domAutomation или navigator.webdriver), попытки обнаружения следов популярных библиотек автоматизации (Puppeteer, Playwright, Selenium) вплоть до проверки наличия их «меток» в коде функций (Function.prototype.toString).
Определение использования headless-режима ведётся по наличию ключевой подстроки «headless» в user agent, что уже давно считается одним из самых простых способов выявить автоматизацию браузера. Для более глубокой проверки собирается информация о графическом процессоре через WebGL: в стандартном режиме браузер сообщает реального производителя видеокарты и рендерер, а в headless часто используется программный рендеринг SwiftShader. Такие данные позволяют классифицировать пользователей и потенциальных ботов с высокой долей вероятности. Важным элементом является проверка на наличие активности Chrome DevTools Protocol (CDP) — технологии, используемой практически всеми инструментами управления браузером. Скрипт реализует ловушку, переписывая геттер свойства stack объекта Error, которая сработает, если происходит сериализация объекта, характерная для взаимодействия с инспектором браузера.
Эта техника позволяет определить, открыт ли девтулс или используется управление браузером на уровне протокола. Все собранные данные систематизируются в единый объект, который затем зашифровывается в функции X и отправляется к backend. Для клиента изменения прозрачны, так как стандартный fetch-полиморфизм кода автоматически подставляет заголовок с сжатием всех утечек. Несмотря на продвинутый уровень сбора данных, текущая Basic версия BotID не слишком строго фильтрует «ботов». Отзывы и эксперименты на Playwright показали, что даже при полном наборе типичных параметров, указывающих на автоматизацию, система нередко принимает запросы за «человеческие».
Это связано с тем, что Vercel, вероятно, накапливает телеметрию для построения более качественных моделей поведения, совершенствуя детекторы постепенно. Обход встроенных проверок Basic BotID сводится к подмене стандартных полей navigator и window — удалению или маскировке javascript-свойств, контролю заголовков user agent, подмене реализации WebGL, а также нейтрализации ловушек с Error.stack. Использование подобных техник может обеспечить для исследователя режим прохождения как «человека» вплоть до того момента, пока система не станет более агрессивной в фильтрации. Для более продвинутых случаев Vercel предлагает переключение на Deep Analysis — платную услугу с дополнительным слоем защиты от Kasada.
Она использует сложные скрипты с собственной виртуальной машиной, которые собирают гораздо более объемные данные о поведении пользователя, а затем анализируют их с помощью машинного обучения. Разобраться с таким уровнем защиты требует привлечения средств дизассемблирования байт-кода и продвинутого реверс-инжиниринга, которые выходят за рамки обычного веб-анализа. Основной урок из изучения BotID — несмотря на прозрачность и простоту использования, современные антиботы серьезно усложняют задачу обхода, используя глубокий анализ браузера и криптографию для подтверждения надежности сигналов. Они создают всё более жесткие критерии для определения легитимности посетителей, что, с одной стороны, защищает ресурсы, а с другой — сужает спектр «приемлемых» пользователей и влияет на приватность. Для разработчиков важно понимать, что на данном этапе технологии как Basic, так и Deep Analysis требуют постоянного мониторинга и адаптации по мере развития платформ.