Mutation Probes & Token Lifecycle
Probe anti-fraud mutations with stacked-rejection detection and track token freshness.
Both features live in the Collector workspace of the API view. Mutation probes actively replay altered requests to map what an anti-fraud system tolerates; token lifecycle passively reads your captures to work out the session economics. Only run probes against systems you are explicitly authorized to test — each probe sends live requests to the target.
[!WARNING] Mutation probes deliberately send tampered traffic (rotated cookies, forged device fields) to a production anti-fraud backend. That is active testing. Confirm you have authorization for the target before clicking Run probe.
Run a mutation probe
Open the Collector workspace → Probes tab. The panel takes one captured request plus a list of single-field mutations:
- Pick the Probe target request from the session/request picker.
- In the Mutations box, choose a location, type the field name and replacement value, then click Add. Repeat for each field you want to test.
- Leave Pairwise pass checked (it shows the pair count,
N×(N−1)/2) and click Run probe.
The probe replays a baseline (the request as captured), then one replay per single mutation, then one replay per pair. Execution is chunked under the backend’s 50-request batch cap, and the button shows live done/total progress.
How mutations are applied
Each mutation targets one location. Cookie and body mutations preserve everything else in the request:
| Location | What it rewrites |
|---|---|
header | Sets or overrides the named request header. |
cookie | Rewrites the named cookie inside the Cookie header (appended if absent); all other cookies are kept. |
query | Sets the named query parameter on the request URL. |
body-json | Sets a dot-path field in the JSON request body, e.g. data.cs.gssc. |
[!NOTE] Pairwise is enabled by default only when there are 12 or fewer mutations, since the pair count grows quadratically. Uncheck it to run singles only.
Stacked-rejection detection
The point of the pairwise pass is the case the singles pass cannot see: two mutations that are each accepted alone but rejected in combination. A pair is flagged a stacked rejection when both of its single mutations were accepted and the combined replay was not. Stacked rows are highlighted in the report and trigger a warning toast. The summary line reads, for example, 3/4 mutations accepted alone; 2 pairs rejected when stacked.
Read the probe report
The results table lists baseline, singles, then pairs with their HTTP status and verdict. A replay is accepted when the server returned no rejection class and a 2xx/3xx status; redirects count as accepted because replay never follows them. Otherwise the verdict shows the rejection class:
| Rejection class | Meaning |
|---|---|
antifraud-reject | Anti-fraud rejection (HTTP 451). |
unauthorized / forbidden / not-found | HTTP 401 / 403 / 404. |
rate-limited | HTTP 429. |
client-certificate-required | mTLS gate (400 with a client-cert body). |
client-error / server-error | Other 4xx / 5xx. |
transport-error | No response (timeout, skipped, connection failure). |
A mutation that flips the baseline from accepted to antifraud-reject identifies a field the anti-fraud logic binds to. See /docs/en/replay/workbench/ for the full rejection vocabulary and /docs/en/replay/fingerprints/ for controlling the TLS fingerprint on replay.
Device-identity consistency rules
When you run a conformance diff (Collector → Conformance tab → Run conformance diff), the same pass runs device-identity rules over the subject capture’s decoded telemetry bodies and request headers. They catch an internally inconsistent device fingerprint before the server does. Violations show as a ruleId badge plus message (up to 10 listed):
| Rule | Severity | Checks |
|---|---|---|
android-sdk-release | high | AndroidSDK int belongs to the declared AndroidRelease (e.g. release 13 → SDK 33). |
display-dims | high | Logical display = ceil(px / (dpi/160)). |
platform-hardware | high | sysInfo platform equals PhoneHardware. |
ua-build-tag | high | User-agent Build/<tag> equals PhoneID. |
fingerprint-release / -brand / -device | warning | Build.FINGERPRINT parts match release, brand, device. |
device-model-cardinality | high | One device-id claims more than one model (must be 1:1). |
session-device-cardinality | warning | One device-id rotated through more than 3 session cookies. |
The fields that must move together are therefore SDK↔release, pixel dims↔density, platform↔hardware, UA build tag↔PhoneID, and device-id↔model. Mutating one without the others is exactly what these rules — and the server — flag.
Track token lifecycle
The conformance pass also builds a token-lifecycle report for the subject session. It is passive: it reads Set-Cookie response headers and token-shaped JSON response fields as mint events (JSON fields are named json:<leaf>, so data.cs.gssc becomes json:gssc), request cookies as consume events, and notes when a minted value later travels in a request URI. Each distinct value is tracked by an 8-char-plus-length fingerprint, and every response it appears in is recorded as an outcome.
A value went stale when it succeeded (status < 400, no rejection) and was later rejected. From that, each token gets a staleness class:
| Staleness | Assigned when |
|---|---|
freshness-bound | ≥2 tracked values and ≥50% succeeded then were rejected. |
single-use-suspected | ≥3 values and ≥80% appear exactly once. |
reusable | Values observed, none went stale. |
unknown | Not enough data to decide. |
For stale tokens the report computes a freshness window (min/median/max milliseconds between last success and first rejection). The panel lists the top 10 tokens with name, staleness badge, and minted N× · consumed N× · in URIs N×.
Read the session-model hints
Above the token list, the report emits plain-language hints that map directly onto how a collector should treat each token:
- Bootstrap once, reuse: minted tokens that never went stale — fetch once and reuse the tuple.
- Derive or refresh per request: single-use or freshness-bound tokens — recompute or re-mint each send (see /docs/en/replay/variables/ for computed fields and /docs/en/collector/signatures/ for recovering the derivation).
- Minted outside the capture: consumed but never minted in the recording — an external bootstrap step is required before replay.