Сессионные рецепты и экспорт Go-коллектора

Сессионная экономика bootstrap-once/per-request и экспорт автономного Go-клиента.

Сессионный рецепт фиксирует, в чём экономия API-сессии: какой вызов единожды создаёт сессионный кортеж, как долго этот кортеж остаётся валидным и какие поля нужно пересчитывать при каждой отправке. Когда рецепт совпадает с наблюдаемым трафиком, Traffic Jam транспилирует его — вместе с кодеком декодирования, функциями вывода и обвязкой mTLS — в автономный Go-коллектор, который можно собрать и запустить вне воркспейса. Обе функции находятся в API lab на вкладке Collector → представление Recipes.

Сессионная экономика: bootstrap один раз, вывод на каждый запрос

Рецепт — это упорядоченный список шагов, каждый со своей ролью:

РольКогда выполняетсяНазначение
bootstrapОдин раз за сессию, пока его извлечения устарелиСоздаёт сессионный кортеж (например, вызов /event, возвращающий сессионные куки/значения CSRF). Его извлечения кэшируются и переиспользуются.
per-requestПри каждом запуске рецептаСобственно рабочий вызов; производные поля (подписанные куки, метки времени, nonce) пересчитываются при каждой отправке.

Свежесть bootstrap ограничена двумя регуляторами, оба опциональны (0 = без ограничений):

  • max age (секунды) — bootstrap перезапускается, когда последний запуск старше этого значения.
  • max uses — bootstrap перезапускается после того, как столько запусков рецепта использовали кортеж.

Пока кортеж свежий, шаги bootstrap пропускаются (отчёт о запуске показывает skipped (fresh)), и срабатывают только шаги per-request. Неудачный bootstrap инвалидирует сессию и немедленно останавливает запуск.

Сборка рецепта из наблюдаемого трафика

  1. Откройте API lab, переключитесь на вкладку Collector, затем на представление Recipes.
  2. В разделе New recipe введите Name и границы свежести bootstrap (по умолчанию: 600 секунд, 25 использований).
  3. Выберите запрос Bootstrap и запрос Per-request из загруженных сессий захвата.
  4. Объявите извлечения bootstrap, по одному на строку, в формате name=source:expression:
gssc=json:data.cs.gssc
cfids=json:data.cs.cfids
token=header:X-Session-Token
trace=regex:"traceId":"([0-9a-f]+)"

Поддерживаемые источники: json (путь через точки, начальный $. опционален), header, cookie (из Set-Cookie) и regex (первая группа захвата или всё совпадение). 5. Нажмите Store recipe. Рецепт сохраняется в базу проекта (с зеркалом в localStorage под ключом traffic-jam:session-recipes как офлайн-кэш); состояние запуска (время последнего bootstrap, счётчик использований, кэшированные извлечения) хранится в localStorage под traffic-jam:recipe-runtimes.

Запуск рецепта

Нажмите Run на рецепте. Раннер проходит шаги по порядку, проигрывая каждый захваченный запрос через обычный путь replay (так что правила безопасности replay по-прежнему действуют). Извлечённые значения bootstrap сливаются с набором переменных, видимых отправлениям per-request, — тот же механизм {{name}}, описанный в /docs/ru/replay/variables/.

Отчёт Last run показывает бейдж по каждому шагу: HTTP-статус, skipped (fresh) для кэшированного bootstrap или error с сообщением. Шаг, чей захваченный запрос больше не загружен, сообщает step request is not loaded.

[!WARNING] Запуски рецепта проигрывают реальные запросы, включая захваченные учётные данные, и автоматически подтверждают методы, меняющие состояние. Запускайте рецепты только против систем, которые вам разрешено тестировать.

Экспорт автономного Go-коллектора

Нажмите Export Go на рецепте. Генератор поднимает эндпоинты, упорядоченные заголовки и куки из захваченного запроса каждого шага, транспилирует ваши шаблоны вывода в Go и скачивает единый main.go.

Выводы объявляются в поле Derivations for collector export, по одному на строку, в формате target = template (разбиение по первому =). Шаблон использует ту же DSL вычисляемых полей, что и replay:

cookie:fgssca-goldapple = p = randomHex:4; p + sha1(fgsscSecret + cookie:gssca-goldapple + p) | skip:4

Транспайлер поддерживает следующие конструкции:

DSLСгенерированный Go
sha1(x), md5(x), sha256(x)tjSha1Hex / tjMd5Hex / tjSha256Hex
hmac-sha1(key, x), hmac-sha256(key, x)tjHmacSha1 / tjHmacSha256
base64(x), crc32(x) (без аргумента → body)tjBase64 / tjCrc32
nowMs(), nowSec(), uuid4(), randomHex:ntjNowMs / tjNowSec / tjUUID / tjRandomHex
cookie:n, header:n, query:n, var:n, bodyпоиск в картах cookie/header/query/var
пайпы | skip:n (trunc), | take:n (prefix), | upper, | lower, | urlencode, | base64tjSkip / tjTake / strings.To* / tjURLEncode / tjBase64
утверждения name = expr; …локальные переменные, чтобы nonce мог совпадать в двух местах

Что содержит сгенерированный код

  • Заголовок DO NOT EDIT by hand — regenerate from the session recipe instead плюс комментарий, описывающий экономику bootstrap max-age/max-uses.
  • sessionState (StartedAt, Uses, Vars) с методом fresh(), кодирующим границы свежести.
  • doRequest — хелпер, который выставляет упорядоченные заголовки, сериализует cookie jar в порядке сортировки имён и ограничивает чтение ответа 4 MiB.
  • По одной функции step_<id> на каждый шаг рецепта: захваченные заголовки и куки, JSON-извлечения через обходчик пути digString, извлечения заголовков через responseHeaders.Get.
  • По одной функции derive_<target> на каждый вывод, вызываемой в run() перед отправлениями per-request.
  • Набор хелперов tj* и пакетный кодек Group-IB (manglePacket/unmanglePacket, позиционно-зависимый сдвиг символов плюс обёртка CRC32).
  • Обвязка mTLS: tls.LoadX509KeyPair, http.Client с таймаутом 30 с, ForceAttemptHTTP2 и MinVersion: tls.VersionTLS12.

Сборка и запуск коллектора

Экспорт скачивает main.go (пакет main). Соберите его как обычный Go-модуль:

mkdir productcard && cd productcard
go mod init productcard
mv ../Downloads/main.go .
go build ./...

Запустите его, указав клиентский сертификат (объединённый PEM с сертификатом и ключом):

CLIENT_CERT=client.pem ./productcard
# or
./productcard -cert client.pem

Флаг -cert по умолчанию берёт $CLIENT_CERT, с фолбэком на client.pem. См. /docs/ru/replay/fingerprints/ о том, как воркспейс управляет клиентскими сертификатами, и /docs/ru/collector/conformance/ о проверке отпечатка коллектора относительно эталонного захвата.

Поведение экспорта и ограничения

ОбластьПоведение
Извлечения regexПодключены к хелперу regexExtract, который возвращает первую группу захвата или всё совпадение, если групп нет.
Цели выводаЦели cookie:name, header:name, query:name, json:path и body автоматически внедряются в запрос.
Нетранспилируемый шаблонЭкспорт отказывается и возвращает ошибку с именем цели вместо выдачи TODO-заглушки для ручного переноса — исправьте шаблон и повторите экспорт.
Переключатели экспорта в UIПанель Recipes всегда выдаёт обвязку mTLS и кодек Group-IB.
Тело bootstrapПри включённом кодеке шаг bootstrap без явного тела отправляет manglePacket(vars["packet"]).
ХранениеРецепты синхронизируются с базой проекта; состояние запуска (время последнего bootstrap, счётчик использований, кэшированные извлечения) живёт только в localStorage браузера и не расшаривается.

[!NOTE] Сгенерированный коллектор — это отправная точка для авторизованного клиента с ограничением частоты против системы, которой вы владеете или которую вам разрешено тестировать: перед запуском проверьте выдаваемые заголовки, тела и обработку сертификатов.

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