TLS engine (JA4_b cipher identity) changed within one session

net.ja4_unstable_within_session  ·  convicts

networklayer
coherencecategory
1evaders caught

What it catches

Within-session TLS coherence — the temporal analog of the cross-layer JA4 tells. A real client speaks ONE TLS engine for a session's lifetime, so its JA4_b (the GREASE-free, sorted cipher-suite hash) is invariant across EVERY connection: transport (H2/H3), TLS resumption (0-RTT/PSK) and Chrome's per-connection extension+GREASE shuffle all leave the cipher list — hence JA4_b — untouched. Two distinct JA4_b under one ks_sid is therefore a single client rotating its TLS fingerprint mid-session (Chrome→Firefox→Safari cipher lists), which a real browser cannot do — the signature of a JA4-rotation evader defeating per-connection JA4 blocklists but forgetting that the SESSION correlates the rotation. The detector derives network.ja4_unstable in ingest.merge over the pre-collapse per-request JA4 history (the store otherwise keeps only the latest JA4 per kind — the architectural blind spot this rule closes); the flag is sticky once a rotation is seen. FP-safe by construction: JA4_b is GREASE-filtered and cipher-sorted (edge ja4.go ja4b), so no real browser varies it within a session; browserforge calibration carries no JA4 layer, so promotion cannot raise its legit-browser flag rate. GROUNDED LIVE 2026-06-20: the go-tls KS_ROTATE evader (uTLS rotating HelloChrome/HelloFirefox/HelloSafari/HelloEdge/HelloIOS across connections under one ks_sid) trips it; every single-engine evader (all 40+ Chrome impersonators + the headful real-browser captures, one JA4_b each) does NOT — zero FP. Caveat (documented, same class as net.tcp_os_vs_ua's proxy confound): a TLS-terminating forward proxy that re-originates a session's connections through different egress TLS stacks could in principle present >1 JA4_b; the lab edge is the first hop (sees the client directly), so the residual is an external-proxy edge case, not an in-fleet FP.

Signals it reads

network.ja4_unstable

How it fires

present

Evaders it caught 1

Bypassed by 10

Frontier evaders that reach the detector uncaught (scored only suspicious, defeating every convicting tell) — this check is not one that stops them. The red-team frontier this detection still has to convict.

← all detections