Skip to main content
Blog
Blog Attacks

TLS fingerprinting in 2026: what the ClientHello reveals (and where the signal fails)

TLS fingerprinting identifies the client library from the ClientHello handshake, before a single byte of HTTP is decrypted. Here is what it catches, what it misses, and where it belongs in a full detection stack.

Jul 19, 2026 6 min read
TLS fingerprinting: what the ClientHello reveals about the client library

TL;DR: TLS fingerprinting

  • Identifies the client library from the ClientHello before any HTTP is decrypted. Your WAF cannot do this. Your CDN can.
  • One hash lookup catches 40-70% of naive bots: curl, requests, headless Playwright without stealth. Sophisticated bots forge theirs.
  • On its own it is partial. Paired with browser fingerprint and behavioral analysis it is your cheap layer-one filter.

TLS fingerprinting — three ways to compute it

Why TLS fingerprinting exists at all

Every TLS 1.2 or 1.3 handshake starts with the client sending a ClientHello message. The ClientHello contains:

  • A list of cipher suites the client supports
  • A list of TLS extensions (SNI, ALPN, session tickets, elliptic curves, and dozens more)
  • The order the client presents them in
  • The TLS version, curves, and signature algorithms

Different HTTP client libraries and different browsers ship with different defaults. Chrome's ClientHello looks different from Firefox's. Firefox looks different from Safari. Python's requests library looks different from all three. Go's net/http looks different again. Headless Playwright looks like Chromium but with a subtly different extension ordering (until you configure otherwise).

If you hash the ClientHello into a short string, you get an identifier that persists across IP addresses, across user agents, and across cookies. That is a TLS handshake fingerprint.

What TLS fingerprinting actually catches

The single biggest use case: identifying non browser clients that pretend to be browsers via the User-Agent header. curl and Python requests are the classic examples. Both are trivial to configure to send a Chrome user agent string. Neither can lie about their TLS handshake fingerprint without significant additional work.

Concrete signals TLS fingerprinting lights up:

  1. Vanilla curl, curl/8.4.0 shipped by default: hash unique to the curl OpenSSL stack. Cannot pass for Chrome without recompilation.
  2. Python requests: uses the operating system's OpenSSL. Hash unique per Python version and OS. Nothing like Chrome's.
  3. Go net/http (unforged): distinctive crypto/tls handshake pattern. Widely used in scraper and API abuse bots.
  4. Headless Playwright with default settings: sends a Chrome ClientHello but with a subtle extension ordering difference. Detectable in the handshake hash.
  5. Legacy scraper stacks (Scrapy default, Puppeteer without stealth): distinct enough hashes to sink 90 percent of the naive bot layer.

For sites without behavioral detection, TLS fingerprinting alone catches 40 to 70 percent of automated traffic depending on the site's popularity as a scraping target. Popular targets attract more sophisticated attackers who forge their fingerprints, which pushes the catch rate down.

What TLS fingerprinting catches on your site

Where TLS fingerprinting fails

Three failure modes matter in 2026.

1. Fingerprint spoofing tools are commodity

utls is a Go library that lets an attacker send an arbitrary ClientHello. curl-impersonate is a patched curl build that ships preset ClientHello templates for Chrome 116, Chrome 119, Safari 17, and so on. Multiple public forge and impersonation projects on GitHub cover every real browser version.

An attacker who uses any of these sends a TLS handshake hash indistinguishable from real Chrome. A defender looking at TLS fingerprints alone sees Chrome and lets the request through. This is not a hypothetical. The tooling is public, actively maintained, and used at scale.

2. Fingerprint entropy has a hard ceiling

There are only so many TLS client library variants in circulation. Chrome accounts for roughly 65 percent of desktop browser traffic in 2026. Safari another 20. Firefox 5. Edge 8 (also Chromium based). Real browser fingerprints cluster into a few dozen buckets at most, because major browsers ship the same crypto stack for months at a time.

That means every legitimate user shares a TLS handshake hash with millions of others. TLS fingerprinting can flag NOT Chrome. It cannot flag "which Chrome." It is a coarse filter, not a per user identifier.

3. TLS terminators strip the signal

By the time an HTTPS request reaches your application server, TLS has been decrypted. If the terminator (nginx, HAProxy, ALB, CDN) does not export the handshake hash as a request header, your application never sees it.

Cloudflare and Fastly both expose TLS handshake identifiers to their customers via custom request headers. Native AWS ALB does not currently expose a TLS handshake hash as of 2026. Native nginx requires a module. If you terminate TLS yourself with plain nginx or HAProxy in front of your origin, you need to install the module and configure the header explicitly.

How TLS fingerprinting fits into a full detection stack

TLS fingerprinting is one signal. On its own it is a cheap dismissal of unsophisticated bots. In combination with the other three detection layers it is a piece of a coherent detection stack:

  1. Network layer (TLS fingerprint, IP reputation, ASN): cheap, catches the bulk of naive traffic.
  2. Browser layer (device fingerprint, navigator.webdriver, CDP artifacts): catches headless Chrome, Playwright, and Selenium even when TLS fingerprints are forged.
  3. Behavioral layer (mouse dynamics, timing, action sequence): the only layer that catches LLM driven agents and stealth Playwright with forged everything.

See our bot detection layers guide for the full pattern.

The honest recommendation

If you are terminating TLS behind Cloudflare or Fastly and not using TLS handshake fingerprinting, turn it on. It costs nothing and eliminates a large fraction of your bot traffic in one hash lookup.

If you are terminating TLS yourself and not using it, install the module (nginx has one, HAProxy has one). Same reason.

If you are already using TLS fingerprinting and you think it is a complete bot defense, you are wrong. The other 30 to 60 percent of automated traffic is either forging its handshake or using a real browser under automation. Behavioral detection is the layer that catches those.

TLS fingerprinting is a cheap, fast, well engineered layer one filter. Treat it as that. Do not treat it as an oracle.

How cside uses TLS fingerprinting

We use TLS handshake fingerprinting as one of the five signals in our VPN and proxy detection stack, and as an early filter in our AI agent detection platform. The signal is cheap enough to compute on every request. The value is in dismissing 40 to 70 percent of unsophisticated bot traffic before any application logic runs. The remaining sophisticated bots are what our behavioral detection stack catches.

If your stack ends at TLS fingerprinting, you have a partial defense. If your stack starts at TLS fingerprinting, you have an efficient one.

TLS fingerprint in a cside session

Mike Kutlu
Client-Side Security Consultant

Client-side security consultant at cside. 10+ years of experience implementing technology solutions for enterprises (previously at Oracle, Cloudflare, and Splunk). Now helping teams use client-side intelligence to catch & reduce fraud.

FAQ

Frequently Asked Questions

TLS fingerprinting hashes the client's ClientHello handshake message (cipher suites, extensions, elliptic curves, and the order they appear in) into a short string that identifies the client library or bot framework before a single byte of HTTP is exchanged.

Yes, and the tooling is public. Libraries like utls (Go), curl-impersonate, and BrowserForge let an attacker send a ClientHello that hashes to Chrome, Safari, or Firefox on demand. TLS fingerprinting alone is not a defense. It is one signal in a stack, and its value is in cheap identification of the naive bot majority.

Most WAFs sit behind a TLS terminating load balancer or CDN. By the time the request hits the WAF, the original ClientHello is gone and only decrypted HTTP remains. TLS fingerprinting has to happen at the TLS terminator itself. Cloudflare and Fastly expose this signal to their customers. If your WAF is behind either of them, you can access it. If you terminate TLS yourself with plain nginx or HAProxy, you need to enable it explicitly.

For an average e commerce or SaaS site, TLS fingerprinting alone catches 40 to 70 percent of automated traffic in a single hash lookup. The remaining 30 to 60 percent is either sophisticated bots that forge their fingerprints or real browsers running under automation. Behavioral detection is the layer that catches those.

cside uses TLS handshake fingerprinting as one of five layers in our VPN and proxy detection stack. We combine the network signal with browser fingerprint, behavioral cadence, and cross session correlation. TLS fingerprinting alone is one signal. In the stack, it is the fastest and cheapest way to flag headless Playwright and curl based scrapers before they even reach your application logic.

Monitor and Secure Your Third-Party Scripts

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Start free, or try Business with a 14-day trial.

cside dashboard interface showing script monitoring and security analytics
Related Articles
Book a demo