Conformance diff

Сравнение вашего парсера/коллектора с эталонным захватом: статусы, порядок заголовков, JA3/JA4, токены.

Diff отвечает на один вопрос: увидит ли anti-fraud-гейт сервера трафик вашего парсера отличным от трафика реального приложения? Передайте ему два захвата — эталонный (reference) от настоящего клиента и исследуемый (subject) от вашего коллектора, парсера или replay-прогона — и он сообщит обо всех измеримых структурных расхождениях: дрейф распределения статусов, сигнатуры порядка HTTP/2-заголовков, порядок и разбиение cookie, JA3/JA4 по каждому SNI, наборы ключей декодированных тел, а также связки «выпуск → использование» токенов с дельтами времени.

Это доведённая до продукта версия ручного цикла сравнения через analyze_traffic.py. Мотивация проста: anti-fraud-гейты редко отклоняют запрос по одному громкому сигналу — они копят тихие. Неправильный порядок заголовков, переставленная пара cookie и слишком быстрое повторное использование токена по отдельности выглядят безобидно; вместе они превращаются в 451. Diff выводит все измерения рядом, чтобы вы могли закрыть их за один раз.

[!NOTE] Этот сценарий предназначен для сравнения трафика систем, которые вы имеете право тестировать. Diff пассивен — он сравнивает два захвата, которые у вас уже есть, и ничего не отправляет ни на какой сервер.

Загрузка эталонного и исследуемого захватов

Сначала импортируйте оба захвата (/docs/ru/capture/importing/):

  1. Эталон (reference): запись pcap/pcapng (или HAR) реального приложения, в идеале с TLS keylog, чтобы были доступны JA3/JA4 и расшифрованные тела.
  2. Исследуемый (subject): вывод вашего коллектора — pcap, записанный во время работы вашего парсера, или история replay, захваченная обратно в рабочее пространство (/docs/ru/replay/fingerprints/ описывает управление TLS-отпечатком, которое делает replay сопоставимым).

Обе сессии должны быть доступны в API-лаборатории. Чем полнее импорт (наличие keylog, настроенный пайплайн декодирования), тем больше измерений diff способен охватить.

Запуск diff

Откройте API lab → вкладка Collector → представление Conformance (по умолчанию), затем:

  1. Выберите захват реального приложения в поле Reference (real app).
  2. Выберите захват вашего парсера/replay в поле Subject (parser / replay).
  3. При желании задайте Path filter — подстроку для сопоставления с путями запросов (например, /catalog/product/card), чтобы ограничить diff одним эндпоинтом.
  4. При желании задайте Join cookie — имя токена, по которому связываются носители и минтеры (например, __gsac_a-goldapple). Оставьте поле пустым — тогда diff сам определит наиболее частый общий cookie.
  5. Нажмите Run conformance diff.

В том же прогоне для исследуемого захвата оцениваются правила device-identity и отчёт о жизненном цикле токенов; оба результата появляются под секциями diff.

Как читать результаты

Отчёт начинается со списка находок, отсортированного по серьёзности; каждая находка соответствует классу расхождений:

НаходкаСерьёзностьЗначение
Status drift: 451 appears N× in subject vs M× in referencehigh (для 4xx/5xx), иначе warningИсследуемый получает статусы, которых нет у эталона; исследуемый с преобладанием 4xx/5xx мгновенно проваливает итерацию.
Header-order signature differs on METHOD host/pathwarningСамая частая упорядоченная последовательность имён заголовков для эндпоинта различается.
Cookie order differs on METHOD host/pathwarningИмена cookie идут в другом порядке внутри заголовка Cookie.
TLS fingerprint differs for SNI (JA4 … vs reference …)highНабор JA3 или JA4 для данного SNI не совпадает.
Join field "X" disagrees in N joined pairswarningЗаголовок носителя расходится со значением, объявленным в теле запроса-минтера.
Subject capture conforms to the reference on all measured dimensionsinfoРасхождений нет ни по одному измеренному измерению.

Под находками таблица Status distribution показывает количество по каждому статусу для обеих сторон (строки с дрейфом подсвечены), а TLS per SNI перечисляет каждый хост с бейджем match/drift. Распределение классов отклонений разбивает ответы на такие метки, как accepted, antifraud-reject (451), rate-limited (429) и client-certificate-required (ответ 400, в теле которого называется недостающий клиентский сертификат).

Секции отчёта подробно

Каждая секция сравнивает эталон и исследуемый по ключу эндпоинта (METHOD authority+path) и выводит топ сигнатур с каждой стороны — до 8 образцов на секцию — с вердиктом matches для самой частой записи:

СекцияЧто сравнивает
Header-order signaturesУпорядоченные последовательности имён заголовков запроса (в нижнем регистре, псевдозаголовки HTTP/2 с : исключены).
Cookie ordersПорядок имён cookie внутри каждого заголовка Cookie, по эндпоинтам.
Cookie header countsСколько заголовков Cookie несёт каждый запрос — ловит различия в разбиении заголовков.
TLS per SNIУникальные наборы JA3, JA4 и ALPN по каждому серверному имени; хост совпадает только когда совпадают и набор JA3, и набор JA4.
Body keysetsОтсортированные JSON-пути ключей (два уровня вглубь) декодированных тел запросов по эндпоинтам — дрейф формы схемы.
Token joinСм. ниже.

Связки токенов и дельты времени

Когда join cookie задан или определён автоматически, diff классифицирует запросы каждой стороны как минтеры (ответ установил cookie через Set-Cookie) или носители (запрос его отправляет), а затем связывает носители с минтерами по точному значению cookie. Блок связки сообщает:

  • количество пар joined / unmatched для обеих сторон;
  • Δt min/median/p90/max — задержка между выпуском токена и его первым использованием, в секундах. Повторное использование токена через 0,1 с после выпуска, когда реальное приложение ждёт секунды, — это временна́я улика;
  • requests before first mint — запросы-носители, предшествующие любому событию выпуска, — трафик без bootstrap, который реальное приложение никогда бы не породило.

Базовый отчёт может также проверять согласованность полей через связку — например, что заголовок plaid-os-version в последующих запросах равен mobileSdk.data.text.AndroidSDK из декодированного тела запроса-минтера.

Типичные исправления по классам расхождений

РасхождениеТипичное исправление
Дрейф статусов в 451/403Это симптом, а не причина — проработайте поведенческие строки ниже, затем перемерьте.
Сигнатура порядка заголовков различаетсяОтправляйте заголовки запроса в захваченном порядке; большинство HTTP-стеков по умолчанию сортируют или переставляют их.
Порядок cookie различается / разбиениеСериализуйте cookie в наблюдаемом порядке имён как один заголовок Cookie (или с тем же разбиением, что использует приложение).
TLS-отпечаток различаетсяПодгоните ClientHello — используйте захваченные JA3/JA4 как целевой отпечаток для replay/коллектора (/docs/ru/replay/fingerprints/).
Набор ключей тела различаетсяПриведите JSON-схему декодированного запроса в соответствие: те же ключи, та же вложенность, никаких лишних отладочных полей.
Δt связки или запросы до выпуска не теВоспроизведите последовательность bootstrap и ритм выпуска токенов приложения, вместо того чтобы выпускать и отправлять их подряд.

[!TIP] Исправьте один класс, перезапустите diff и убедитесь, что его находка исчезла, прежде чем двигаться дальше — список находок служит вашей регрессионной проверкой. Когда каждое измерение соответствует, но комбинированные изменения всё равно отклоняются, переключитесь на представление Probes: оно прогоняет одиночные и парные мутации и помечает накопленные отклонения — мутации, которые принимаются по отдельности, но отклоняются в сочетании.

Документация Traffic Jam. Собрано с помощью Hugo.