Антифрод-стек выдачи Яндекса [08/2026] v1.0
Базис reverse-engineering · антифрод
Антифрод выдачи Яндекса Справочник факторов детекта: что и как измеряется, чтобы отличить живого пользователя от автоматики
Разбор двух реальных скриптов Яндекса — серпового трекера watch_serp.js и антибот-фингерпринтера @yandex-lego/powaas. Ниже — каталог сигналов, которые оборона снимает на каждом слое, и вывод, который она из отклонений делает.
Документ описывает только сторону детекта
Легенда происхождения
watch_serp.js.@yandex-lego/powaas (FingerprintJS-based, обфусцированный бандл).Как устроена оборона сейчас
Современный антифрод Яндекса — не разовая проверка, а непрерывный процесс без чёткого начала и конца: правила накладываются друг на друга и меняются постоянно. Устроен он послойно и работает по принципу накопления доверия (траста) к сессии, а не по одному стоп-фактору.
На входе оценивается сеть — траст к IP и подсети. Дальше сверяется отпечаток устройства: у антифрода есть внутренняя база «доверенных» фингеров, с которой сравнивается текущий. Параллельно снимается поведение в выдаче и собирается фингерпринт через отдельный антибот-модуль (@yandex-lego/powaas). Итог — не бинарный «бот/не бот», а накапливаемый вес доверия к профилю, который может и обнуляться.
Ключевой сдвиг последнего времени — переход от прямых блокировок (ошибки 429) к экономическому давлению через proof-of-work: при низком трасте клиент заставляют выполнять всё более тяжёлые вычисления. Отсюда рост капчи и нагрузки на CPU. То есть защита теперь бьёт не столько по факту доступа, сколько по стоимости массовых сессий — это и есть смысл слоёв ниже.
Эшелон обороны
Антифрод — не одна стена, а решётка независимых слоёв: от происхождения трафика и отпечатка устройства до поведения, кликов и агрегатной статистики. Сигнал проходит их по порядку, вес подозрительности копится, и решение — капча, лимит или обесценивание клика — принимается по совокупности, а не по одному признаку. Ниже разобран каждый слой: что он проверяет и зачем.
01Сетевой / IP-слойдо JS 02Окружение и фингерпринт устройствакто/что 03Детект автоматизацииbot? 04Идентичность и репутация сессиидоверие 05Поведенческие сигналыестественность 06Клики и удовлетворённостьядро ПФ 07Запрос и структура сессиипаттерн 08Агрегатные и временные аномалииcross-session 09Серверный вердикт и инфраструктурарешениеСетевой / IP-слой
источник: общее + powaas (WebRTC)Самый ранний рубеж — на уровне соединения, ещё до исполнения JS. Здесь антифрод смотрит не на поведение, а на происхождение запроса: откуда он пришёл и можно ли доверять источнику. Оценивается тип адреса и репутация подсети, а также согласованность IP с таймзоной и языком. Отдельно — WebRTC/STUN: он вскрывает реальный адрес за NAT, поэтому попытка спрятаться за прокси видна как рассинхрон реального и заявленного IP.
Ваши данныеВаш реальный IP и примерная геолокация, ваш интернет-провайдер. WebRTC способен раскрыть настоящий адрес даже при включённом VPN.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Траст IP / подсети | Тип адреса (датацентр vs резидентный/мобильный), ASN, история запросов с подсети | Низкий траст источника → порог доверия резко растёт | [общее] |
| Прокси / VPN | Признаки анонимизации соединения | Скрытие реального адреса → рост подозрительности | [общее] |
| Гео-согласованность | Совпадение IP-гео с языком, таймзоной, регионом | Рассинхрон гео и окружения → флаг | [общее] |
| Частота с адреса | Плотность запросов с одного IP | Ненормальный ритм → лимитирование/капча | [общее] |
| WebRTC / STUN | Реальный IP за NAT через STUN (stun4.l.google.com) | Реальный адрес ≠ IP соединения → детект VPN/прокси | [powaas] |
Окружение и фингерпринт устройства
источник: watch_serp.js + powaasСпособ узнать устройство даже без кук. Скрипт снимает десятки признаков — экран, GPU, canvas, аудио, набор шрифтов, сенсоры, локаль — и сворачивает их в единый хеш. Антифрод сравнивает этот отпечаток со своей базой, и важна не только уникальность, но и внутренняя непротиворечивость: реальные устройства согласованы между собой, а эмуляция часто противоречит сама себе (например, GPU говорит одно, а платформа — другое).
Ваши данныеПочти уникальный «слепок» вашего устройства (экран, видеокарта, шрифты, звук). Позволяет узнавать вас между сайтами и в инкогнито — вообще без кук.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
hidv2 | Аппаратный отпечаток (асинхронный хеш), цепляется к хиту | Узнавание без кук; несогласованность отпечатка → флаг | [код] |
GPU / WebGL (gpu-get) | Данные видеокарты и рендерера | «Пустые»/софт-рендер значения → подозрение на эмуляцию | [код] |
Экран и вьюпорт (sr) | Разрешение, глубина цвета, devicePixelRatio | Нереалистичные комбинации → флаг | [код] |
| Платформа / языки | platform, navigator.languages | Несогласованность с гео/таймзоной → флаг | [код] |
Таймзона (z) | Смещение часового пояса | Конфликт с IP-гео и языком → флаг | [код] |
| Поддержка фич | Куки, тач-флаг, возможности API | Профиль «слишком чистый» → подозрение | [код] |
| Согласованность фингерпринта | Совпадение всех признаков между собой | Внутренние противоречия → сильный сигнал автоматизации | [общее] |
| Canvas 2D | Рендер и toDataURL 2D-контекста | Типовой хеш эмулятора → флаг | [powaas] |
| WebGL расширенно | getParameter VENDOR/рендерер, getExtension, ошибки контекста | Софт-рендер/подставной GPU → подозрение | [powaas] |
| Аудио-фингерпринт | OfflineAudioContext, getChannelData | Аномалия рендера звука → различающий признак | [powaas] |
| Энумерация шрифтов | measureText + инъекция скрытых элементов | Нетипичный набор шрифтов → флаг | [powaas] |
| Согласованность локали | Intl.DateTimeFormat.resolvedOptions, offset | Конфликт локали/таймзоны/языка → флаг | [powaas] |
| Расширенные сенсоры | enumerateDevices, bluetooth, permissions, голоса TTS, ориентация | «Пустой» набор → подозрение на эмуляцию | [powaas] |
| Fullscreen-префиксы | fullscreenElement и вендорные webkit/moz | Рассинхрон движка с UA → флаг | [powaas] |
| Адблок / фильтр-листы | Скрытие известных рекламных селекторов | Какие фильтры активны → доп. признак | [powaas] |
| Архитектура сбора | factorCollectors → hashBinary | Все факторы сворачиваются в единый отпечаток-хеш | [powaas] |
Детект автоматизации
источник: watch_serp.jsПроверки уже внутри запущенного браузера: ищутся следы, которые оставляют фреймворки автоматизации (WebDriver, Selenium, headless). Ключевая деталь — вердикт не бинарный: скрипт выставляет уровень подозрительности, который дальше складывается с остальными слоями, а не сразу блокирует.
Ваши данныеВ основном технические свойства браузера, а не персональные данные. Для живого человека приватного следа почти не оставляет.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Свойства WebDriver | Наличие __webdriver_evaluate, __selenium_evaluate и родственных | Присутствие → признак фреймворка автоматизации | [код] |
navigator.webdriver | Стандартный флаг автоматизации | true → прямой признак управляемого браузера | [код] |
| Набор признаков | Сверка со списком selenium/webdriver/driver | Совпадение → флаг | [код] |
| Headless-режим | Детект HeadlessChrome | Признаки headless → подозрение | [код] |
| Градация вердикта | Итог кодируется степенью (0/1/2/4) | Не «да/нет», а уровень подозрительности | [код] |
| Служебные краулеры | Детект Mediapartners-Google и т.п. по UA | Отделение легальных ботов от пользовательских сессий | [код] |
Идентичность и репутация сессии
источник: watch_serp.jsНасколько сессия узнаваема и «обжита»: есть ли история, устойчивое состояние в хранилищах и связи с внешним id-графом через синхронизацию кук с партнёрами. Свежий профиль без истории и связей вызывает меньше доверия, чем аккаунт с прошлым.
Ваши данныеВаши идентификаторы и связи с сервисами-партнёрами. Именно здесь поисковое поведение сшивается в общий профиль о вас.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
Куки / yandexuid | Наличие и возраст идентификаторов | «Свежая» сессия без истории → меньше доверия | [код] |
| Хранилища | localStorage, indexedDB как устойчивое состояние | Чистое состояние на «старом» устройстве → рассинхрон | [код] |
| Cross-partner sync | Сверка id с партнёрами (match.html, image-check) | Отсутствие связей → анонимность/подозрение | [код] |
| Репутация аккаунта | Залогинен ли, история поведения аккаунта | «Пустой» аккаунт повышает порог; доверенный — снижает | [общее] |
Поведенческие сигналы
источник: watch_serp.jsПоведение оценивается на естественность: значим не факт клика, а то, как человек к нему шёл — траектория курсора, паузы «прочтения», глубина и характер скролла. Скрипт способен записывать сессию целиком (session replay), маскируя чувствительные поля. Идеально ровные тайминги и прямые «телепортные» траектории выдают автоматику.
Ваши данныеКак вы двигаете мышью, листаете и читаете. Запись сессии фиксирует ваши действия на странице — пароли и данные карт при этом маскируются.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Траектория курсора | mousemove: путь, скорость, микропаузы до клика | Прямые/телепортные траектории → неестественность | [код] |
| Hover над сниппетами | Наведения без клика (desktop) | Полное отсутствие hover при кликах → флаг | [код] |
| Тач-поведение | touch*, координаты тапа, инерция скролла (mobile) | Идеально ровные жесты/тайминги → подозрение | [код] |
| Скролл | Глубина относительно pageHeight, скорость, ориентация | Клик без прокрутки к элементу → флаг | [код] |
| Тайминги между действиями | Паузы «прочтения», ритм взаимодействия | Слишком стабильные/машинные интервалы → неестественность | [код] |
| Клавиатура / копирование | keydown/up, copy | Аномальные паттерны ввода → сигнал | [код] |
| Session replay | Запись сессии чанками wv-part (пароли/карты маскируются) | Полная картина сессии для оценки «живости» | [код] |
| Видимость вкладки | visibilitychange, focus/blur | Активность в невидимой вкладке → флаг | [код] |
Клики и удовлетворённость
источник: watch_serp.jsЯдро поведенческих факторов. Клик логируется через редирект с привязкой к запросу и позиции. Но вес клика определяется тем, что происходит дальше: быстрый возврат в выдачу (pogosticking) обесценивает его, а завершение сессии на результате читается как удовлетворённость. Аномальный CTR относительно ожидаемого для позиции — отдельный сильный сигнал.
Ваши данныеЧто вы искали, по какому результату кликнули и насколько он вас устроил — то есть ваши интересы и намерения.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Клик + позиция | Логирование через /clck/jsredir (from, etext, state, uuid) | Связка запрос→позиция→URL→момент сессии | [код] |
| CTR по позиции | Кликабельность относительно ожидаемой для места | Аномально высокий CTR на низкой позиции → сильный флаг | [общее] |
| Возврат к выдаче | Быстрый возврат в SERP после клика (pogosticking) | Результат не удовлетворил → минус сайту | [код] |
| Dwell time | Время между кликом и возвратом | Короткий dwell → неудовлетворённость | [общее] |
| Последний клик | На каком результате завершилась сессия | Маркер «нашёл, что искал» | [общее] |
| Распределение кликов | Разброс кликов по выдаче в потоке сессий | Концентрация на одном URL → неестественный паттерн | [общее] |
Запрос и структура сессии
источник: общееАнтифрод смотрит не только на отдельный клик, но и на форму всей сессии. Живой поиск имеет контекст: уточнения, разные формулировки, переходы. Массовые заходы по одному идеально точному ключу без вариаций и «плоские» сессии без предыстории — характерный машинный паттерн.
Ваши данныеТексты ваших запросов и логика поиска — прямое отражение того, что вам интересно прямо сейчас.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Переформулировки | Уточняет ли пользователь запрос | Естественная доработка vs шаблонный точный вход | [общее] |
| Поисковая сессия | Последовательность запросов и переходов | «Плоские» сессии без контекста → подозрение | [общее] |
| Точность запроса | Заход по идеально точному ключу без вариаций | Массовый вход по одному ключу → паттерн накрутки | [общее] |
| Источник входа | Прямой заход на выдачу vs органический путь | Аномальные источники сессий → флаг | [общее] |
Агрегатные и временные аномалии
источник: общееДаже безупречная отдельная сессия проявляется на массе — здесь работает статистика. Всплески объёма по запросу или URL, общий «почерк» у множества сессий, неестественная форма CTR-кривой и эффекты, которые не закрепляются во времени, видны только в агрегате и часто приводят к откату.
Ваши данныеВаше поведение в сравнении с массой и во времени. Отдельные записи обезличены, но общий паттерн всё равно различим.
| Фактор | Что измеряется | На что указывает отклонение | Пров. |
|---|---|---|---|
| Всплески объёма | Резкий рост кликов/сессий по запросу или URL | Ненормальная динамика → флаг | [общее] |
| Скоординированность | Схожесть поведения across многих сессий | Общий «почерк» у массы сессий → сильный сигнал | [общее] |
| Форма CTR-кривой | Соответствие ожидаемому распределению по позициям | Искусственно ровная/перевёрнутая кривая → аномалия | [общее] |
| Ретеншн-эффект | Держится ли эффект во времени | Всплеск без органического закрепления → откат/пессимизация | [общее] |
Серверный вердикт и инфраструктура
источник: watch_serp.js + powaasГде собирается итоговый вердикт и как гарантируется доставка сигнала. Отдельно стоит PoW (proof-of-work): вместо прямого бана подозрительная сессия получает вычислительную задачу, и чем выше подозрительность — тем она тяжелее. Это переносит нагрузку на клиент и бьёт по массовой автоматике не баном, а стоимостью.
Ваши данныеПередачу собранного на серверы Яндекса. Proof-of-work вдобавок расходует ресурсы вашего процессора.
| Компонент | Роль | Пров. |
|---|---|---|
/clck/jsredir | Логгер кликов: запрос→позиция→URL, реферер зашифрован (etext) | [код] |
adstat.yandex.ru/track | Antifraud/stat-трекинг, привязка к сессии | [код] |
solid.ws (WebSocket) | Real-time канал телеметрии | [код] |
| SmartCaptcha | Барьер при подозрении: вместо прямого бана — smart / слайд / текст-капча | [общее] |
| Ретрай/надёжность | reqNum, retryReqs, wserrs — гарантия доставки даже при быстром уходе | [код] |
Proof-of-Work (powaas) | Активный вычислительный челлендж; удорожает массовую автоматизацию | [powaas] |
Два скрипта — два уровня одной обороны
Вместе они закрывают больше, чем каждый по отдельности: один смотрит на поведение, другой — на подлинность.
watch_serp.js
зона: что делает пользователь
Трекер поведения на выдаче — клики, скролл, курсор, session replay, надёжная доставка сигнала.
@yandex-lego/powaas
зона: настоящий ли это пользователь
Антибот-фингерпринтер — факторы устройства (canvas/WebGL/audio/шрифты/сенсоры), реальный IP через WebRTC/STUN, proof-of-work.
- Сетевой детект не заканчивается на IP соединения. WebRTC/STUN вскрывает реальный адрес за NAT — VPN/прокси ловятся по рассинхрону, а не только по репутации подсети.
- Фингерпринт глубже, чем
hidv2/gpu-get. Powaas добавляет аудио, canvas-2D, энумерацию шрифтов, сенсоры и согласованность локали — и сворачивает всё в единый хеш. Устройство опознаётся плотнее и без кук. - Появляется активная защита, а не только пассивные измерения. Proof-of-work заставляет клиент считать: цена одной сессии растёт, что бьёт по массовости напрямую.


