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 whosenameis 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 text —
Bearer/Basictokens, 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/Cookievalues 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:
| Control | Behavior |
|---|---|
| Redirects | Never followed. The replay surfaces the redirect response itself, since following could mutate another endpoint or forward custom credential headers. |
| Timeout | Defaults to 30 s; the dialog’s Timeout (seconds) field accepts 1–120. |
| Response preview | Capped at 4 MiB (replayResponseBodyLimit); larger bodies are flagged truncated. |
| Credentials | Excluded by default; sent only with the explicit opt-in above. |
| Batch size | Bulk replay is capped at 50 requests per batch. |
| State-changing methods | Require 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 withTRAFFIC_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:8790by default (TRAFFIC_JAM_ADDR). - Capability token — set
TRAFFIC_JAM_API_TOKENon the API and the same value asVITE_TRAFFIC_JAM_API_TOKENfor the web frontend; clients send it in theX-Traffic-Jam-Tokenheader, 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 origintraffic-jam://appare allowed. Add exact origins with the comma-separatedTRAFFIC_JAM_ALLOWED_ORIGINS. Any otherOriginis 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.