Chromium-JA4 session repeated one TLS extension order (no per-connection permutation)

net.tls_ext_order_static_within_session  ·  convicts

networklayer
coherencecategory
4evaders caught

What it catches

Within-session TLS extension-ORDER coherence — the FIFTH member of the within-session network-invariant family (net.ja4_unstable_within_session = TLS engine, net.h2_unstable_within_session = HTTP/2 stack, net.ip_rotation_within_session = origin, net.ua_rotation_within_session = UA; this = the ClientHello extension ORDER), and the INVERSE shape: the siblings convict on >1 distinct value (a fixed field that rotated), this convicts on EXACTLY 1 distinct value where a real client MUST vary it. Chromium (BoringSSL) PERMUTES its ClientHello extension order on EVERY connection since ~Chrome 110 (uTLS ShuffleChromeTLSExtensions replicates it), so a real Chromium emits a DIFFERENT network.tls_ext_order — the raw GREASE-normalised wire order JA4 *sorts* away (edge fingerprint/grease.go ExtOrder) — per connection. A session whose JA4 identifies a Chromium engine yet repeats a SINGLE extension order across >=2 connections is a pinned template that copied Chrome's cipher list, GREASE and extension SET (so its JA4 hints chrome and it carries GREASE + a PQ key share — net.tls_vs_ua_browser / tls_grease_vs_ua / tls_pq_keyshare_vs_ua all stay quiet) but NOT Chrome's per-connection permutation. CRITICALLY NON-REDUNDANT with the family: JA4 sorts the extension list, so a pinned-order template keeps ONE JA4_b (ja4_unstable never fires) and can hold its h2/IP/UA fixed too — every other tell stays silent while the un-permuted order is the only contradiction. The detector derives network.tls_ext_order_static in ingest over the pre-collapse per-connection tls_ext_order history (gated to a Chromium ja4_browser_hint so Firefox/Safari — which do NOT permute — and unhinted JA4s can never convict; sticky once tripped). FP-safe BY CONSTRUCTION and grounded in-process (edge fingerprint/tls_ext_order_test.go): TestRealChromePermutesExtensionOrder proves uTLS HelloChrome_131 (real Chrome's permuter) emits 3 DISTINCT orders across 3 hellos — a real Chromium can never present a static order, so the rule cannot fire on it; TestPinnedSpecStaticExtensionOrder proves a reused HelloChrome_131 spec emits a byte-IDENTICAL order across connections while still GREASEing and carrying a PQ key share — so even a CURRENT Chrome hello, when pinned, leaves the static order as the ONLY residual tell — and that its JA4 hints chrome (the gate precondition). browserforge calibration carries no network layer, so promotion cannot raise its legit-browser flag rate (same class as its JA4/h2/IP/UA siblings). GROUNDED LIVE 2026-06-25: the go-tls KS_STATICEXT evader pins a STALE non-shuffling Chrome template (uTLS HelloChrome_102 — pre-2023 Chrome that GREASEs + carries Chrome's cipher list, so its JA4 hints chrome, but does NOT permute) and replays it across 3 connections under one ks_sid → the edge emits the SAME tls_ext_order three times, the detector accumulates >=2 identical orders under a chrome JA4 hint and trips this rule (label bot, captured as corpus/sessions/go-tls-static-ext.json, frozen by test_lit_rule_captures); single-connection and per-connection-permuting clients (every real-browser capture) do NOT fire it — zero FP. (A pinned CURRENT hello would isolate this as the sole tell; the stale 102 template additionally trips net.tls_pq_keyshare_vs_ua, which is fine — the rule fires independently.) Residual caveat (documented, same external-proxy class as net.ja4_unstable's): a TLS-terminating forward proxy that re-originates a session's connections through ONE pinned egress stack could present a static order, but the lab edge is the first hop (sees the client directly), so that residual is an external-proxy edge case, not an in-fleet FP.

Signals it reads

network.tls_ext_order_static

How it fires

present

Evaders it caught 4

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