Safety & Sensitive Data

How Traffic Jam masks secrets, gates replay, and keeps capture data local.

Traffic Jam handles captured credentials, session tokens, and PII by default. Its safety model has three layers: secrets are masked in analysis views and stripped from shareable exports, replay is gated behind explicit confirmations, and all capture data stays on your machine. This page collects the exact behavior in one place.

[!NOTE] Traffic Jam is a tool for authorized security testing and API reverse engineering. Only capture, replay, and probe systems you have permission to test.

What is masked in analysis views

Masking is name- and pattern-based. A value is masked when its field name looks credential-bearing or when the value itself matches a known secret pattern.

Headers masked by exact name:

Header
authorization, proxy-authorization
cookie, set-cookie
x-api-key, x-auth-token, x-access-token, x-session-token
x-csrf-token, x-xsrf-token

Any header whose name contains api-key, auth, credentials, jwt, secret, session, sign/signature, or token, or ends with a compact suffix such as password, privatekey, clientsecret, samlresponse, or sessionid, is also treated as sensitive. Tracing identifiers are explicitly not secrets: traceparent, tracestate, x-correlation-id, x-device-id, x-request-id, x-timestamp.

Query and fragment parameters follow the same field-name rules plus the exact names code, key, and sig.

In the UI, masked values render as a non-copyable preview that keeps the auth scheme and the last four characters so you can still tell tokens apart:

Bearer ••••••••3f2a
••••••••        (values of 8 characters or fewer)

Structured bodies are redacted in place, preserving shape:

  • JSON — values of sensitive field names become "<redacted>"; object keys that contain embedded credentials become "<redacted-key>".
  • application/x-www-form-urlencoded — sensitive parameter values become <redacted>.
  • multipart/* — parts whose name is sensitive are replaced with <redacted>; nested parts are redacted recursively.
  • XML/HTML markup — sensitive attributes and the text content of sensitive elements are redacted.
  • Plain textBearer/Basic tokens, JWTs (eyJ…), and known credential patterns are replaced.

Recognized value patterns include AWS keys (AKIA…), GitHub tokens (ghp_, gho_, github_pat_), Stripe keys (sk_live_, pk_), Slack tokens (xox[baprs]-), and Google API keys (AIza…).

URL userinfo, path segments under credential contexts (auth, oauth, token, callback, reset, verify, and friends), and sensitive query values are redacted wherever URLs appear, including inside Location, Referer, Content-Location, and Link headers.

Redaction in exports and copies

Generated curl, Python, Postman, and OpenAPI examples are redacted by default; exact captured values require an explicit opt-in. Header values export as deterministic placeholders (Bearer <redacted>, name=<redacted> per cookie pair) rather than the UI’s •••• preview, so exported text is safe to paste into a report.

Bodies that cannot be inspected safely are not leaked: in shareable exports an opaque body is replaced with the placeholder <redacted: opaque body> (or <redacted: opaque multipart body>).

Catalog exports carry a safety manifest and report so you can see exactly what was withheld:

{
  "version": 2,
  "policy": {
    "capturedSensitiveValues": "redacted",
    "opaqueBodies": "omitted",
    "pathCredentials": "redacted"
  },
  "report": {
    "routes": 12, "calls": 340,
    "headerRedactions": 28, "bodyRedactions": 9,
    "urlRedactions": 4, "opaqueBodies": 2, "truncatedBodies": 1
  }
}

With the opt-in enabled, the policy fields flip to included-by-explicit-opt-in. The report also warns when captured bodies were truncated (inferred contracts may be incomplete) or when opaque bodies were omitted. Path templates are sanitized too: credential-looking segments become {redacted} and credential-named parameters become {parameter1}, while ordinary UUIDs and numeric IDs are left intact. See /docs/en/analysis/exports/.

Reveal opt-in

Masking is the default everywhere; revealing exact values is a deliberate, session-scoped act.

  • Analysis views — open the Settings dialog and enable Reveal secrets. The toggle is application-wide but session-only: it resets when the app reloads.
  • Replay — in the Replay dialog, captured credentials are excluded until you check Include captured credentials in this replay (the shield-warning toggle). Only then are the real Authorization/Cookie values placed on the wire.

Replay safety gates

Replay is designed to expose a single captured endpoint’s behavior without side effects. The backend and the workbench enforce these defaults:

ControlBehavior
RedirectsNever followed. The replay surfaces the redirect response itself, since following could mutate another endpoint or forward custom credential headers.
TimeoutDefaults to 30 s; the dialog’s Timeout (seconds) field accepts 1–120.
Response previewCapped at 4 MiB (replayResponseBodyLimit); larger bodies are flagged truncated.
CredentialsExcluded by default; sent only with the explicit opt-in above.
Batch sizeBulk replay is capped at 50 requests per batch.
State-changing methodsRequire confirmation (below).

Before sending, the workbench checks the method. Anything other than GET, HEAD, or OPTIONS is treated as potentially state-changing, and Send stays disabled until you tick Confirm potentially state-changing request. Editing the target URL raises a separate destination-change confirmation.

[!WARNING] Header replacements you type into the workbench are treated as deliberate values and are sent exactly as entered — they are not re-masked. Credential A/B overrides are likewise sent verbatim. Use this to test your own tokens against endpoints you are authorized to probe. See /docs/en/replay/workbench/ and /docs/en/replay/variables/.

Local-only architecture

Nothing leaves your machine except the replays you explicitly send.

  • Storage — parsed sessions persist in SQLite at .traffic-jam/traffic-jam-v2.sqlite3 (override with TRAFFIC_JAM_DB_PATH); live-capture artifacts live under .traffic-jam/live-captures (TRAFFIC_JAM_CAPTURE_DIR). The desktop app stores the database in its user-data directory.
  • Loopback API — the backend listens on 127.0.0.1:8790 by default (TRAFFIC_JAM_ADDR).
  • Capability token — set TRAFFIC_JAM_API_TOKEN on the API and the same value as VITE_TRAFFIC_JAM_API_TOKEN for the web frontend; clients send it in the X-Traffic-Jam-Token header, compared in constant time. The desktop shell generates a fresh random token on every launch and passes it to the backend and renderer through an isolated preload bridge. The standalone dev API accepts unauthenticated requests by default.
  • CORS allowlist — only loopback browser origins (localhost, 127.0.0.1, ::1) and the desktop origin traffic-jam://app are allowed. Add exact origins with the comma-separated TRAFFIC_JAM_ALLOWED_ORIGINS. Any other Origin is rejected with HTTP 403.
export TRAFFIC_JAM_API_TOKEN="$(openssl rand -hex 32)"
export VITE_TRAFFIC_JAM_API_TOKEN="$TRAFFIC_JAM_API_TOKEN"

Full environment reference: /docs/en/reference/cli-config/.

Responsible use

The features that make Traffic Jam useful for reverse engineering — replay, mutation probes, JWT test-token generation (alg=none, RS-to-HS), and credential A/B testing for BOLA/IDOR investigation — are dual-use. They assume you are testing systems you own or are contracted to test. Secrets detection and masking (/docs/en/security/secrets/) exist so you can investigate and report findings without accidentally propagating live credentials into exports, logs, or shared artifacts.

Traffic Jam documentation. Built with Hugo.