Browser Anti-Detection (Part 1): TLS Handshake and HTTP/2 Frames — You're Identified Before JS Runs

TLS handshake fingerprint (JA3/JA4), HTTP/2 SETTINGS frame characteristics, TCP timestamp differences — before you control the browser, the OS and network stack have already identified you.

16Yun Engineering TeamApr 5, 20264 min read

Transport Layer Detection: You're Marked Before You Log In

If you're only concerned about Camoufox's C++ engine-level fingerprinting and Puppeteer Stealth Plugin's JS shims, you're only defending part of the attack surface. There's a whole category of detection you may not even know exists: transport layer detection.

Transport layer detection happens before any JavaScript executes on the page. Before HTML downloads, before CSS starts parsing, before JS begins executing — the TLS handshake between client and server has already completed. And that handshake carries enough signal to determine whether the other end is a real browser.

The key advantage for the detector: this is outside the browser's control.

You modify navigator.webdriver in JavaScript. You spoof Canvas fingerprints. You fake AudioContext output. All of this happens at the application layer. None of it affects transport layer behavior. The TLS handshake is handled by the OS and networking library, not by the page's JavaScript.

JA3/JA4: TLS Handshake Fingerprinting

During the TLS handshake, the client sends a Client Hello message containing:

  • Supported TLS versions
  • Supported cipher suites
  • Supported extensions
  • Supported elliptic curves
  • Signature algorithms

The combination of these parameters — not individual values, but their specific arrangement — forms a TLS fingerprint. JA3 is the classic implementation: hash the parameters from Client Hello to produce a unique identifier.

Different browsers have different TLS fingerprints:

  • Chrome 130's JA3 fingerprint: 771,4865-4866-4867-...
  • Firefox 130's JA3 fingerprint: 771,4865-4867-4866-...
  • curl's JA3 fingerprint: completely different (far fewer cipher suites)

The differences go beyond cipher suite count:

  • Extension ordering: Chrome has a specific extension preference order
  • ALPN protocol list: Chrome supports h2 (HTTP/2); some curl versions don't
  • Elliptic curve ordering: Chrome prefers x25519; curl may use prime256v1

JA4 is an improved version adding TLS 1.3 support and finer-grained feature extraction:

t13d1516h2_8daaf6152771_02713d6af862
  • t13 = TLS 1.3
  • d15 = 15 cipher suites supported
  • 16h2 = 16 extensions, includes h2 protocol
  • Hash values derived from specific parameter values

The JA4 fingerprint from curl -sI https://example.16yun.cn is completely different from Chrome visiting the same page.

HTTP/2 SETTINGS Frame: A Finer Signal Than TLS

If the target site supports HTTP/2 (in 2026, nearly all major sites do), after the TLS handshake the client sends an HTTP/2 SETTINGS frame. This frame carries the client's HTTP/2 configuration.

Chrome's HTTP/2 SETTINGS frame:

SETTINGS_HEADER_TABLE_SIZE: 65536
SETTINGS_ENABLE_PUSH: 0
SETTINGS_MAX_CONCURRENT_STREAMS: 1000
SETTINGS_INITIAL_WINDOW_SIZE: 6291456
SETTINGS_MAX_FRAME_SIZE: 16384
SETTINGS_MAX_HEADER_LIST_SIZE: 262144

curl's SETTINGS frame:

SETTINGS_HEADER_TABLE_SIZE: 4096
SETTINGS_ENABLE_PUSH: 0
SETTINGS_MAX_CONCURRENT_STREAMS: 100
SETTINGS_INITIAL_WINDOW_SIZE: 65535

The differences are striking: HEADER_TABLE_SIZE 65536 vs 4096, INITIAL_WINDOW_SIZE 6291456 vs 65535. Every single parameter differs.

TCP Timestamps and Behavior

Beyond application-layer protocols, subtle TCP-level differences also betray automation:

TCP timestamp options: Linux and macOS kernels generate TCP timestamps at different frequencies. Linux increments every 1ms, macOS every 100ms. If a server receives a "Chrome on macOS" request but sees Linux-frequency TCP timestamps, that's evidence of inconsistency.

Initial Sequence Number (ISN) patterns: Different TCP implementations use different ISN generation algorithms. Detection systems can infer the client OS from ISN patterns.

Window scaling factor: Chrome's default Window Scale value differs from common automation tools.

Why This Matters

The difference between transport layer and JS layer detection: JS layer detection can be bypassed by updating stealth plugins (at least temporarily). Transport layer detection cannot — it's outside JavaScript's control.

Example: You run Camoufox. It modifies all Firefox fingerprint vectors at the C++ engine level. It passes every JS-layer check. But Camoufox's TLS handshake is handled by NSS (Mozilla's network security library), whose behavior differs from Chrome's BoringSSL or curl's OpenSSL. A detection system analyzing your TLS fingerprint can still identify you as not-Chrome.

Practical Countermeasures

Transport layer detection is harder to bypass than JS-layer detection. Limited options exist:

Match the network stack. If the target expects Chrome, ensure your TLS stack behaves like Chrome's BoringSSL. Some anti-detect browsers optimize this by swapping the underlying TLS library.

Maintain consistency. Transport and application layer signals must corroborate each other. TLS handshake says "Chrome on Windows" but User-Agent says "Chrome on macOS" → instant block.

Proxy impact on transport layer. Proxies modify some transport layer characteristics. Tunnel proxies can partially hide TLS fingerprints, but residential proxy + HTTP proxy introduces new artifacts (additional headers). Account for this when configuring proxies.

Not every site uses transport layer detection — it adds complexity and compute cost. But as the anti-bot arms race escalates, more platforms are adopting it. If you maintain high-value scraping channels, this is a problem you'll eventually face.

The next article covers new application-layer detection vectors: Canvas is old news — 2026 is about GPU pipelines, keystroke entropy, and Client Hints.

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.