From JA3 to JA4+: How Modern WAFs Identify Anti-Detect Browsers at the Network Level

· 14 min read
ja4 tls-fingerprinting waf anti-detect network-security
From JA3 to JA4+: How Modern WAFs Identify Anti-Detect Browsers at the Network Level

Ready to protect your online identity?

Choose your plan and start running undetectable browser profiles today.

Get Started

Every time your browser opens an HTTPS connection, the TLS Client Hello packet broadcasts a fingerprint that uniquely identifies the software making the request. For years, JA3 was the de facto standard for capturing this fingerprint. But in 2023, John Althouse — one of JA3’s three original co-creators (along with Jeff Atkinson and Josh Atkins at Salesforce) — published JA4+, a family of fingerprinting methods that rendered most existing anti-detect evasion techniques obsolete overnight. If your multi-accounting setup still relies on JA3 randomization, you are almost certainly being flagged at the network layer before your JavaScript even executes.

This article explains the technical evolution from JA3 to JA4+, why naive randomization strategies fail against the new standard, and what a properly engineered anti-detect browser must do to remain invisible at the network level.

How JA3 Fingerprinting Works

JA3 computes an MD5 hash from five fields extracted from the TLS Client Hello message:

  1. TLS Version — the protocol version advertised by the client
  2. Cipher Suites — the list of supported encryption algorithms, in order
  3. Extensions — the list of TLS extension type codes, in order
  4. Elliptic Curves (Supported Groups) — the named curves advertised
  5. Elliptic Curve Point Formats — the point format types supported

These fields are concatenated with commas and hashed:

JA3 = MD5(TLSVersion,CipherSuites,Extensions,EllipticCurves,ECPointFormats)

A real Chrome 120 JA3 string might look like:

771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,
0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0

The resulting MD5 hash becomes the JA3 fingerprint. Every identical browser build on the same OS produces the same hash, making it trivial to distinguish Chrome from Firefox, or a real browser from a Python requests session.

Why JA3 Randomization Seemed to Work

The JA3 hash is order-dependent. Shuffling the cipher suites or extensions changes the hash entirely. Early anti-detect browsers exploited this by:

  • Randomizing the order of cipher suites per session
  • Injecting dummy extensions (like GREASE values)
  • Varying the advertised supported groups

This worked because JA3-based WAF rules typically maintained allowlists of known-good hashes. A randomized hash didn’t match any known browser, but it also didn’t match any known bot — so it often passed through as “unknown” rather than “blocked.”

The fundamental flaw: randomization produces fingerprints that match no real browser. As soon as defenders started flagging unknown fingerprints rather than just blocking known-bad ones, randomization became a liability.

Enter JA4+: A Fundamentally Different Approach

JA4+ is not a single fingerprint but a family of fingerprinting methods:

FingerprintWhat It Captures
JA4TLS Client Hello (replaces JA3)
JA4STLS Server Hello (replaces JA3S)
JA4HHTTP Client fingerprint
JA4LLight distance / latency
JA4XX.509 TLS certificate
JA4SSHSSH traffic fingerprint
JA4TTCP fingerprint
JA4TSTCP Server Response

The core JA4 fingerprint addresses JA3’s weaknesses through three design decisions that make randomization ineffective.

1. Canonical Sorting Eliminates Order Dependence

JA4 sorts cipher suites and extensions alphabetically before hashing. Two clients offering the same set of ciphers in different orders produce the same JA4 fingerprint. This single change invalidates the most common JA3 evasion technique.

# JA3: order matters
Ciphers: 4865,4866,4867,49195 → hash_A
Ciphers: 49195,4867,4866,4865 → hash_B (different!)

# JA4: canonical sort
Ciphers: 4865,4866,4867,49195 → hash_X
Ciphers: 49195,4867,4866,4865 → hash_X (identical!)

2. Structured Prefix for Quick Classification

JA4 prepends a human-readable prefix before the hash section:

JA4 = t13d1516h2_8daaf6152771_e5627efa2ab1
       │││  ││││││
       ││└──┘│││││
       ││    ││││└─ ALPN first+last char
       ││    │││└── Number of extensions (hex)
       ││    ││└─── Number of cipher suites (hex)
       ││    │└──── SNI presence (d=domain, i=IP)
       ││    └───── TLS version
       │└────────── Protocol (t=TCP, q=QUIC)
       └─────────── (reserved)

This prefix is not randomizable without changing the actual capabilities of the TLS stack. You cannot claim to support 22 cipher suites while only listing 15 — the count is derived from the actual Client Hello content.

3. GREASE Value Exclusion

GREASE (Generate Random Extensions And Sustain Extensibility) values are placeholder extension and cipher codes that browsers inject to test server tolerance. JA4 strips all GREASE values before fingerprinting, so injecting random GREASE codes — another common JA3 evasion trick — has zero effect on the JA4 hash.

How WAFs Use JA4+ in Practice

Modern WAFs like Cloudflare, Akamai, and F5 deploy JA4+ fingerprints in layered detection:

Layer 1: Protocol Consistency Check

The JA4 prefix reveals the TLS version and capability count. A request claiming to be Chrome 124 via User-Agent but presenting a JA4 prefix consistent with Python’s urllib3 is immediately suspicious. The WAF doesn’t even need to compute the full hash.

Layer 2: Known-Browser Matching

Every major browser version on every major OS produces a small set of JA4 fingerprints (typically 1-3 per version/OS combination). WAFs maintain databases of these fingerprints. A request from “Chrome on Windows” whose JA4 doesn’t match any known Chrome-on-Windows fingerprint gets elevated scrutiny.

Layer 3: Cross-Signal Correlation (JA4H)

JA4H fingerprints the HTTP layer: header order, Accept-Language patterns, and other HTTP-level signals. A connection might have a valid JA4 TLS fingerprint but an inconsistent JA4H HTTP fingerprint — revealing that the TLS stack and HTTP stack come from different software.

Layer 4: Network Behavior (JA4L, JA4T)

JA4T captures TCP characteristics (window size, TTL, MSS) that correlate with the operating system. JA4L measures round-trip latency to estimate physical distance. A “user in Tokyo” whose JA4L latency is consistent with US East Coast datacenter routing gets flagged.

# Pseudocode: multi-layer JA4+ validation
def validate_request(request):
    ja4 = extract_ja4(request.tls_client_hello)
    ja4h = extract_ja4h(request.http_headers)
    ja4t = extract_ja4t(request.tcp_metadata)
    
    # Check TLS fingerprint against claimed browser
    claimed_browser = parse_user_agent(request.headers['User-Agent'])
    if ja4 not in KNOWN_FINGERPRINTS[claimed_browser]:
        return ELEVATED_RISK
    
    # Cross-check HTTP behavior
    if ja4h not in EXPECTED_HTTP_PATTERNS[claimed_browser]:
        return ELEVATED_RISK
    
    # Verify OS consistency via TCP stack
    claimed_os = parse_sec_ch_ua_platform(request.headers)
    if ja4t.os_family != claimed_os:
        return BLOCK
    
    return PASS

Why Common Evasion Strategies Fail Against JA4+

Strategy 1: Cipher Suite Randomization

Result: Ineffective. JA4 sorts canonically. The same set of ciphers always produces the same hash regardless of order.

Strategy 2: Extension Injection

Result: Partially detected. Adding extensions changes the extension count in the JA4 prefix, which must match known browser profiles. Real Chrome 124 has exactly N extensions — adding or removing any changes the prefix to a non-matching value.

Strategy 3: Using a Real Browser Engine with Modified Headers

Result: Detected via cross-signal analysis. If you use Chromium’s TLS stack but modify HTTP headers, JA4 and JA4H will be inconsistent. The TLS fingerprint says “Chrome” but the HTTP fingerprint says “custom.”

Strategy 4: Proxying Through a Real Browser’s TLS Stack

Result: Detected via JA4T and JA4L. The TCP fingerprint reveals the proxy’s OS (often Linux, while claiming Windows), and latency measurements expose datacenter routing.

What Proper Anti-Detect Must Do

A genuinely undetectable anti-detect browser must achieve consistency across all JA4+ dimensions simultaneously. This requires architectural decisions that go far beyond configuration:

Full Browser Engine Control

The anti-detect browser must use the actual browser engine (Gecko, Blink) that matches the claimed identity. Santiago uses a patched Camoufox (Firefox/Gecko) engine, which means its TLS stack is genuinely Firefox’s — producing authentic JA4 fingerprints without any simulation.

Network Stack Integrity

The TLS configuration must not be injected via a proxy or middleware. Extensions like encrypted_client_hello, application_layer_protocol_negotiation, and signature_algorithms must come from the browser engine itself, not from a wrapper that intercepts and modifies Client Hello messages.

OS-Level TCP Consistency

TCP parameters (window size, TTL, MSS, window scaling factor, SACK support) must match the claimed operating system. This typically requires either running on the actual OS or using OS-level network stack emulation — not just userspace TCP parameter modification.

# Windows 10/11 typical TCP fingerprint
TTL: 128, Window: 65535, MSS: 1460, WScale: 8, SACK: permitted

# macOS typical TCP fingerprint  
TTL: 64, Window: 65535, MSS: 1460, WScale: 6, SACK: permitted

# Linux typical TCP fingerprint
TTL: 64, Window: 29200, MSS: 1460, WScale: 7, SACK: permitted

Extension-Device Correlation

The TLS extensions advertised must be consistent with the device profile. For example, a profile claiming to be Chrome on Android should not advertise the server_name extension with a pattern typical of desktop Chrome, and should include mobile-specific ALPN values.

QUIC/HTTP3 Awareness

Modern Chrome uses QUIC for many connections. JA4+ includes QUIC fingerprinting (the q prefix). An anti-detect browser that claims to be Chrome but never initiates QUIC connections — or initiates QUIC with a non-Chrome fingerprint — creates a detectable anomaly. The browser must either properly implement QUIC with the correct fingerprint or consistently disable it in a way that matches a realistic network configuration (e.g., corporate firewall blocking UDP 443).

JA4+ Database: The Scale of the Problem

The JA4+ project maintains an open fingerprint database with contributions from major CDN and security vendors. As of early 2026, this database contains:

  • ~1,200 unique JA4 fingerprints for major browser/OS combinations
  • ~400 fingerprints for common automation tools (Playwright, Puppeteer, Selenium)
  • ~800 fingerprints for HTTP client libraries (requests, aiohttp, curl, etc.)

This means WAFs can positively identify most automation tools before any JavaScript runs. The fingerprint is embedded in the very first packet of the TLS handshake — there is no opportunity to intercept or modify it after the fact.

Practical Testing: Verifying Your JA4 Fingerprint

You can check your browser’s JA4 fingerprint using several methods:

Using Wireshark

Wireshark 4.2+ includes native JA4 dissection. Capture traffic on your interface, filter for TLS Client Hello packets, and examine the ja4 field:

tls.handshake.type == 1

Using ja4+ CLI Tools

The official JA4+ tools can analyze PCAP files:

# Capture traffic
tcpdump -i eth0 -w capture.pcap -c 100

# Analyze with ja4
ja4 --pcap capture.pcap --json | jq '.[] | {ja4, ja4h, ja4t}'

Using Online Services

Services like tls.browserleaks.com and tls.peet.ws display your JA4 fingerprint in real-time, allowing you to compare it against known browser databases.

Conclusion

The transition from JA3 to JA4+ represents a paradigm shift in network-level browser fingerprinting. Randomization strategies that worked against JA3 are not just ineffective against JA4+ — they are actively harmful, producing fingerprints that scream “evasion attempt” to any modern WAF.

The only viable approach is authenticity: using a real browser engine with an unmodified network stack, ensuring consistency across TLS, HTTP, TCP, and application layers. Any anti-detect browser that treats network fingerprinting as a configuration problem rather than an architecture problem will be detected by JA4+ — not sometimes, but every time.

Ready to protect your online identity?

Choose your plan and start running undetectable browser profiles today.

Earn 15% lifetime commission on every referral.

Become a Partner →