Как отличить бота от человека без единой строки JavaScript: детекция ботов без JavaScript на уровне сети

Вы установили антифрод-скрипт. Он собирает canvas fingerprint, проверяет WebGL, анализирует движения мыши. Отчёт показывает, что 95% визитов — настоящие люди. Но конверсия падает, бюджет утекает, а заявки не растут. Проблема в том, что современные боты давно научились проходить любые JavaScript-проверки. Детекция ботов без JavaScript — на уровне сетевых протоколов — единственный подход, который невозможно обмануть клиентским кодом.

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

Почему JavaScript-детекция ботов перестала работать

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

Headless-браузеры исполняют JS безупречно

Puppeteer, Playwright и Selenium запускают полноценный движок Chromium или Firefox. Они отвечают на все вопросы антифрод-скрипта ровно так, как отвечает настоящий браузер, потому что они и есть настоящий браузер — просто управляемый программой, а не человеком. Canvas fingerprint, WebGL renderer, AudioContext — всё идентично обычному Chrome.

Антидетект-браузеры подменяют всё

Инструменты вроде Multilogin, GoLogin и Dolphin Anty создают виртуальные профили с полностью настраиваемыми отпечатками. Оператор задаёт конкретный User-Agent, разрешение экрана, набор шрифтов, параметры WebGL — и каждый профиль выглядит как уникальный реальный пользователь. JS-проверка видит «человека из Москвы на Windows 11 с Chrome 124», хотя на самом деле это ферма из 500 профилей на одном сервере.

Скрипты блокируются и модифицируются

Боты могут просто не загружать антифрод-скрипт. Перехват на уровне прокси, подмена ответа сервера, блокировка домена скрипта — всё это тривиальные операции. Даже если скрипт загрузится, его можно модифицировать в рантайме, перехватив API-вызовы через Proxy объекты JavaScript, чтобы он всегда возвращал «чистый» результат.

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

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

Детекция ботов без JavaScript: серверные методы, которые нельзя подделать

Принципиальное отличие серверной детекции в том, что она анализирует данные, которые клиент отправляет ещё до получения контента. Бот не может подделать TCP-пакет так же легко, как значение navigator.userAgent, потому что TCP-стек формируется ядром операционной системы, а не пользовательским кодом.

1. TCP fingerprinting: отпечаток на уровне SYN-пакета

Каждое TCP-соединение начинается с SYN-пакета. В нём операционная система указывает параметры, которые характеризуют её сетевой стек:

  • Window Size — начальный размер окна приёма. Windows, Linux и macOS используют разные значения по умолчанию.
  • MSS (Maximum Segment Size) — максимальный размер сегмента. Зависит от MTU интерфейса и ОС.
  • TTL (Time To Live) — начальное значение. Windows ставит 128, Linux — 64, macOS — 64 с определёнными вариациями.
  • TCP Options и их порядок — набор и последовательность опций (MSS, Window Scale, SACK Permitted, Timestamps, NOP) уникальны для каждой ОС и её версии.

Что это даёт: если User-Agent заявляет Chrome на Windows 11, а TCP fingerprint соответствует Linux-серверу — перед нами автоматизация из дата-центра. Бот не может подменить эти параметры без модификации ядра ОС или использования специализированного сетевого стека, что на порядок сложнее, чем подмена JS-свойства.

2. TLS fingerprinting: JA3, JA4 и анализ ClientHello

При установке TLS-соединения клиент отправляет сообщение ClientHello, которое содержит детальную информацию о его криптографических возможностях:

  • Наборы шифров (Cipher Suites) — их список и порядок уникальны для каждого TLS-клиента.
  • TLS-расширения — какие расширения поддерживает клиент, в каком порядке они указаны.
  • Поддерживаемые группы и форматы точек эллиптических кривых — характеристики криптографии.
  • Версия TLS — реальная поддерживаемая версия (не только объявленная).

Эти данные агрегируются в хеши JA3 и JA4. Chrome 124 на Windows имеет конкретный JA3-хеш. Python-библиотека requests — совершенно другой. Golang net/http — третий. Даже если бот подменил User-Agent на строку Chrome, его TLS-отпечаток выдаёт реальный клиент.

Важный момент: TLS ClientHello отправляется до того, как сервер вернёт хотя бы один байт контента. Детекция происходит мгновенно, с нулевой задержкой для пользователя.

Существуют библиотеки, которые пытаются имитировать TLS-отпечаток Chrome (например, utls для Go или tls-client для Python). Однако они требуют постоянного обновления вслед за каждым релизом браузера и часто отстают, создавая характерные «полу-Chrome» отпечатки, которые сами по себе становятся маркером автоматизации.

3. HTTP/2 fingerprinting: отпечаток на уровне протокола

HTTP/2 — стандартный протокол для современных браузеров, и его реализация тоже уникальна для каждого клиента:

  • SETTINGS frame — при установке HTTP/2-соединения клиент отправляет фрейм с настройками: HEADER_TABLE_SIZE, ENABLE_PUSH, MAX_CONCURRENT_STREAMS, INITIAL_WINDOW_SIZE, MAX_FRAME_SIZE. Значения и их порядок специфичны для каждого браузера.
  • Порядок псевдо-заголовков — Chrome отправляет :method, :authority, :scheme, :path. Firefox использует другой порядок.
  • Приоритеты потоков — схема приоритизации запросов (weight, dependency) различается между браузерами.
  • WINDOW_UPDATE — стратегия управления потоком данных.

HTTP/2-отпечаток — один из самых надёжных маркеров, потому что его крайне сложно подделать. Для этого нужно написать собственную реализацию HTTP/2-стека, полностью имитирующую поведение целевого браузера.

4. IP-репутация и ASN-анализ

Каждый IP-адрес принадлежит автономной системе (ASN), и тип этой системы — мощный сигнал:

  • Дата-центровые IP — адреса Amazon AWS, Google Cloud, DigitalOcean, Hetzner и сотен других хостинг-провайдеров. Настоящий пользователь крайне редко заходит на сайт с IP дата-центра.
  • Residential IP — адреса домашних интернет-провайдеров. Ожидаемый источник реального трафика.
  • Mobile IP — адреса мобильных операторов. Легитимный мобильный трафик.
  • Residential proxy — отдельная категория: IP формально жилой, но используется через прокси-сеть. Выявляется по базам известных прокси-сервисов и по поведенческим аномалиям.

ASN-анализ не даёт стопроцентного вердикта сам по себе, но в комбинации с другими сигналами резко повышает точность. Визит с IP Amazon AWS, где JA3-хеш соответствует Python requests, а User-Agent заявляет Chrome — это бот с вероятностью, близкой к абсолютной.

Распространённая тактика ботоводов — покупка резидентных прокси для маскировки дата-центровых IP. Но даже при использовании жилого IP остальные сетевые отпечатки (TCP, TLS, HTTP/2) по-прежнему выдают автоматизацию. Резидентный прокси меняет только последний хоп — он не может изменить то, как клиент формирует TCP-пакеты или TLS-сообщения.

5. Анализ HTTP-заголовков

Порядок и состав HTTP-заголовков — ещё один маркер, который сложно подделать:

  • Порядок заголовков — браузеры отправляют заголовки в определённой последовательности. Chrome ставит sec-ch-ua перед sec-ch-ua-mobile. Скрипт на Python расставит их иначе.
  • Accept-Language — настоящий браузер отправляет язык ОС с приоритетами (например, ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7). Бот часто ставит en-US или забывает этот заголовок вовсе.
  • Отсутствие заголовков — современный Chrome отправляет sec-ch-ua, sec-fetch-dest, sec-fetch-mode и другие Client Hints. Их отсутствие при заявленном Chrome User-Agent — верный признак подделки.
  • Консистентность — User-Agent говорит «macOS», а Accept-Language содержит только zh-CN без упоминания английского. Формально возможно, но статистически крайне маловероятно для типичного трафика.

6. Версия TLS и поддержка шифров

Отдельно стоит обратить внимание на уровень криптографической поддержки:

  • Только TLS 1.2 — все современные браузеры поддерживают TLS 1.3. Клиент, который подключается только по TLS 1.2, — это либо устаревший корпоративный софт, либо скрипт на старой версии библиотеки.
  • Отсутствие современных шифров — если ClientHello не содержит TLS_AES_128_GCM_SHA256 и TLS_AES_256_GCM_SHA384, клиент не соответствует профилю современного браузера.
  • Необычный набор шифров — некоторые HTTP-клиенты (curl, wget, httpx) имеют характерные наборы шифров, которые мгновенно идентифицируют их, независимо от User-Agent.

Почему серверная детекция ботов без JavaScript превосходит клиентскую

Фундаментальное преимущество серверного подхода — асимметрия затрат. Подделать значение JavaScript-свойства — одна строка кода. Подделать TCP-стек — месяцы работы с сетевым ядром. Подделать TLS-отпечаток — написание собственной TLS-библиотеки. Подделать всё одновременно и консистентно — задача, которую решают единицы.

Работает до загрузки страницы. Серверные методы анализируют соединение на этапе TCP handshake и TLS negotiation. Решение принимается за миллисекунды до того, как сервер отправит хотя бы один байт HTML. Для легитимного пользователя задержка равна нулю.

Невозможно заблокировать. JS-скрипт можно не загрузить, модифицировать или подменить. TCP SYN-пакет и TLS ClientHello — обязательные части протокола. Без них соединение просто не установится.

Не зависит от контента. Серверная детекция работает одинаково для HTML-страниц, API-запросов, загрузки изображений — для любого HTTP-взаимодействия. JS-детекция работает только на страницах, куда встроен скрипт.

Единая точка контроля. Серверная детекция покрывает все домены и поддомены, маршрутизируемые через прокси. Не нужно встраивать скрипт в каждую страницу, проверять, что он не упал, не был заблокирован AdBlock-ом и корректно загрузился. Один инфраструктурный слой — и всё защищено.

Сравнительная таблица: JS-детекция против серверной детекции ботов без JavaScript

Критерий JS-детекция Серверная детекция
Момент срабатывания После полной загрузки страницы и исполнения скрипта На этапе TCP/TLS handshake, до отправки контента
Headless-браузеры (Puppeteer, Playwright) Не обнаруживает — движок идентичен реальному браузеру Обнаруживает по TLS/HTTP/2 отпечатку и IP дата-центра
Антидетект-браузеры Не обнаруживает — все отпечатки подменены Частично обнаруживает по аномалиям TCP/TLS
Скрипты (Python, Go, curl) Не работает — скрипты не исполняют JS Обнаруживает мгновенно по TLS/TCP/HTTP fingerprint
Блокировка защиты Скрипт можно заблокировать или подменить Невозможно — протокольный обмен обязателен
Влияние на скорость загрузки Добавляет 50-200 мс на исполнение скрипта Нулевое — анализ происходит в рамках handshake
API-запросы Не покрывает — скрипт не встроен в API Полное покрытие всех HTTP-запросов
Поведенческий анализ (мышь, клавиатура) Да Нет — требует JS как дополнительный сигнал
Сложность обхода для атакующего Низкая — одна строка JS Высокая — требует модификации сетевого стека

Реальный сценарий: идеальный JS-отпечаток, пойманный по TLS

Рассмотрим конкретную ситуацию. На рекламную кампанию в Яндекс.Директ приходит трафик. JS-антифрод-система рапортует: всё чисто. Canvas fingerprint — уникальный. WebGL renderer — NVIDIA GeForce RTX 3060. User-Agent — Chrome 124 на Windows 11. Мышь двигается, клавиатура работает, скролл естественный.

Но серверная система видит другую картину:

  1. TCP fingerprint показывает Linux-ядро версии 5.x. Для «Windows 11» — явное несоответствие.
  2. JA3-хеш TLS ClientHello не совпадает ни с одним известным хешем Chrome 124. Вместо него — хеш, характерный для модифицированной TLS-библиотеки на базе BoringSSL.
  3. HTTP/2 SETTINGS фрейм содержит значения INITIAL_WINDOW_SIZE и MAX_CONCURRENT_STREAMS, не соответствующие ни одному известному браузеру.
  4. IP-адрес принадлежит ASN Hetzner — крупнейшему европейскому хостинг-провайдеру.
  5. Порядок HTTP-заголовков не совпадает с паттерном Chrome — отсутствуют заголовки sec-ch-ua-platform и sec-fetch-user.
  6. Каждый из этих сигналов по отдельности — повод для подозрения. Вместе они дают однозначный вердикт: это автоматизация. Антидетект-браузер идеально подменил все JS-отпечатки, но не смог изменить поведение сетевого стека операционной системы и TLS-библиотеки.

    JS-антифрод этот визит пропустил бы. Рекламный бюджет был бы потрачен впустую.

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

    Архитектура обратного прокси для серверной детекции

    Для реализации серверной детекции ботов без JavaScript оптимальна архитектура обратного прокси (reverse proxy). Прокси-сервер размещается между клиентом и веб-сервером. Весь трафик проходит через него, при этом для клиента и для сервера прокси полностью прозрачен.

    Как это работает:

    1. Клиент открывает TCP-соединение с прокси. Прокси анализирует SYN-пакет и фиксирует TCP fingerprint.
    2. Клиент инициирует TLS handshake. Прокси извлекает ClientHello, вычисляет JA3/JA4-хеш, фиксирует TLS fingerprint.
    3. Клиент отправляет HTTP/2 SETTINGS. Прокси анализирует параметры и порядок псевдо-заголовков.
    4. Прокси сопоставляет все собранные отпечатки с заявленным User-Agent и IP-репутацией.
    5. Решение принимается за микросекунды: пропустить запрос к целевому серверу, заблокировать или пометить для дополнительного анализа.
    6. Ключевое преимущество: ни клиент, ни веб-сервер не знают о существовании промежуточного слоя. Сайт не нужно модифицировать. Скрипты не нужно встраивать. DNS-запись меняется один раз — и защита начинает работать для всех страниц, API и статических ресурсов одновременно.

      Технологии, которые делают это возможным на уровне ядра ОС — eBPF (extended Berkeley Packet Filter). eBPF-программы встраиваются в сетевой стек Linux и анализируют каждый пакет с минимальными накладными расходами, без копирования данных в пользовательское пространство и без влияния на производительность.

      Для владельца сайта интеграция выглядит максимально просто: DNS A-запись домена меняется на IP прокси-сервера, и с этого момента каждый входящий запрос проходит через слой серверной детекции. Установка скриптов, модификация кода сайта, интеграция через Tag Manager — ничего из этого не требуется.

      Комбинированный подход: сервер как первичный фильтр, JS как дополнительный сигнал

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

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

      Второй эшелон — JavaScript-анализ. Для трафика, прошедшего серверный фильтр, собирает дополнительные сигналы: поведенческий анализ (движение мыши, паттерны скролла, скорость набора), аппаратные отпечатки (canvas, WebGL, AudioContext), проверка на аномалии DOM.

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

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

      Заключение

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

      Детекция ботов без JavaScript — на уровне TCP, TLS, HTTP/2 и IP-репутации — работает там, где клиентский код бессилен. Она анализирует то, что нельзя подделать без фундаментальной переработки сетевого стека. Она срабатывает до загрузки страницы. Она покрывает не только HTML, но и API, статику и любые HTTP-запросы.

      Если вы управляете рекламным бюджетом или отвечаете за качество трафика — задайте вашему антифрод-провайдеру простой вопрос: «Что именно вы анализируете на сетевом уровне, до исполнения JavaScript?» Ответ на него покажет, насколько серьёзна защита.

Scroll to Top