Summary
The technical specification for JA4T is severely lacking in the repo -
technical_details/ contains only JA4T.png, and the only textual
definitions are a one-line table entry in technical_details/README.md, a
single example string in the root README, external blogs, and a format
comment in rust/ja4/src/tcp.rs:121-126.
Without a spec, the three implementations that do exist (Rust, Wireshark,
Zeek) have drifted apart on four edge cases. In each case Wireshark and Zeek
agree with each other and Rust differs (as at commit 0e54bc8).
More detail
1. Empty TCP options placeholder
For a SYN carrying zero TCP options:
- Rust joins an empty options vector, leaving the field empty - e.g.
64240__0_0 (rust/ja4/src/tcp.rs:128-134).
- Wireshark emits
00 (wireshark/source/packet-ja4.c:666-680).
- Zeek emits
00 (zeek/ja4t/main.zeek:198-202).
2. Absent MSS and window-scale formatting
- Rust prints
unwrap_or(0) with no padding -> 0
(rust/ja4/src/tcp.rs:139-140).
- Wireshark and Zeek print
%02d -> 00 (packet-ja4.c:668-677;
zeek/ja4t/main.zeek:204-210).
A SYN with no MSS and no window-scale option is 65535_00_00_00 in
Wireshark/Zeek but 65535__0_0 in Rust (combined with 1 above).
3. Duplicated MSS / window-scale options
If MSS or window-scale appears more than once in the options list:
- Rust takes the first occurrence (
rust/ja4/src/tcp.rs:76-85).
- Wireshark and Zeek overwrite on each occurrence, so the last wins
(packet-ja4.c:1461-1466; zeek/ja4t/main.zeek:109-114).
(The ordered option-kind list itself is handled identically everywhere - no
implementation deduplicates it.)
4. ECN-flagged SYNs
A SYN negotiating ECN sets CWR and ECE (flags 0xC2):
- Rust detects an initial SYN via bitmask (SYN set, ACK clear), explicitly
ignoring CWR/ECE; a unit test asserts 0xC2 is accepted
(rust/ja4/src/tcp.rs:14-15,145-159).
- Wireshark requires
tcp_flags == 0x02 exactly (packet-ja4.c:1266) - an
ECN-setup SYN produces no JA4T.
- Zeek requires flags equal to
TH_SYN exactly (zeek/ja4t/main.zeek:126)
So ECN-capable clients are fingerprinted by Rust and silently invisible to
Wireshark and Zeek.
Ask
- Publish a
technical_details/JA4T.md defining the field layout
(window_size_options_mss_windowscale) and the canonical behavior for:
empty options, absent MSS/window-scale, duplicated options, and which TCP
flag combinations qualify as a fingerprintable SYN.
- Align implementations.
Summary
The technical specification for JA4T is severely lacking in the repo -
technical_details/contains onlyJA4T.png, and the only textualdefinitions are a one-line table entry in
technical_details/README.md, asingle example string in the root README, external blogs, and a format
comment in
rust/ja4/src/tcp.rs:121-126.Without a spec, the three implementations that do exist (Rust, Wireshark,
Zeek) have drifted apart on four edge cases. In each case Wireshark and Zeek
agree with each other and Rust differs (as at commit
0e54bc8).More detail
1. Empty TCP options placeholder
For a SYN carrying zero TCP options:
64240__0_0(rust/ja4/src/tcp.rs:128-134).00(wireshark/source/packet-ja4.c:666-680).00(zeek/ja4t/main.zeek:198-202).2. Absent MSS and window-scale formatting
unwrap_or(0)with no padding ->0(
rust/ja4/src/tcp.rs:139-140).%02d->00(packet-ja4.c:668-677;zeek/ja4t/main.zeek:204-210).A SYN with no MSS and no window-scale option is
65535_00_00_00inWireshark/Zeek but
65535__0_0in Rust (combined with 1 above).3. Duplicated MSS / window-scale options
If MSS or window-scale appears more than once in the options list:
rust/ja4/src/tcp.rs:76-85).(
packet-ja4.c:1461-1466;zeek/ja4t/main.zeek:109-114).(The ordered option-kind list itself is handled identically everywhere - no
implementation deduplicates it.)
4. ECN-flagged SYNs
A SYN negotiating ECN sets CWR and ECE (flags
0xC2):ignoring CWR/ECE; a unit test asserts
0xC2is accepted(
rust/ja4/src/tcp.rs:14-15,145-159).tcp_flags == 0x02exactly (packet-ja4.c:1266) - anECN-setup SYN produces no JA4T.
TH_SYNexactly (zeek/ja4t/main.zeek:126)So ECN-capable clients are fingerprinted by Rust and silently invisible to
Wireshark and Zeek.
Ask
technical_details/JA4T.mddefining the field layout(
window_size_options_mss_windowscale) and the canonical behavior for:empty options, absent MSS/window-scale, duplicated options, and which TCP
flag combinations qualify as a fingerprintable SYN.