Skip to content
Fingerprinting

Chrome's version is not one number: patch levels, platforms and the client hints

The User-Agent says 156.0.0.0. The client hints say which of eight Windows builds you run, and Linux never got half of them.

Pim
Pim· Clearcote Research
6 min read

Key takeaways

  • Since User-Agent reduction, the User-Agent string carries only the major version (Chrome/156.0.0.0), but navigator.userAgentData.getHighEntropyValues(['fullVersionList']) and the Sec-CH-UA-Full-Version-List header expose the full build.
  • In its first two weeks, Chrome 156 stable shipped eight builds on Windows (.35, .36, .47, .48, .49, .73, .74 and an early 157.0.8103.15) but only two on Linux (.47 and .73).
  • A full version has to exist for the claimed platform and be plausible for the date: Linux never shipped 156.0.8078.74, and a build that is weeks old describes a user who has not updated.

What the User-Agent stopped saying

Chrome's User-Agent string used to carry the full build, for example Chrome/156.0.8078.73. Since User-Agent reduction it carries only the major version followed by zeros: Chrome/156.0.0.0. The detail moved to User-Agent Client Hints: a server that asks for it with Accept-CH receives Sec-CH-UA-Full-Version-List, and any page can call navigator.userAgentData.getHighEntropyValues(['fullVersionList']).

A deployed challenge widget makes exactly that call, together with architecture, bitness, formFactor, model and platformVersion. So the build number still matters; it just moved.

How many builds one version has

A Chrome major version is not one build. Chromium Dash lists the stable releases per platform, and Chrome 156's first two weeks looked like this:

  • Windows: 156.0.8078.35 and .36 (14 October, early stable), .47 and .48 (20 October), .49 and 157.0.8103.15 as early stable for the next major (22 October), .73 and .74 (27 October).
  • macOS: .35, .36, .47, .48, .49, .73 and .74.
  • Linux: .47 (20 October) and .73 (27 October). Nothing else.
  • Android: .39, .47, .48, .49, .73 and an early 157.0.8103.14.

Several builds often ship on the same day. Updates roll out gradually, so on any given day the real population of a platform is a mix of the last few builds, weighted toward the newest.

What a full version can contradict

  • The platform. A full version that never shipped on the claimed platform is impossible: Chrome on Linux reporting 156.0.8078.74, or on Windows reporting a build that only Android received.
  • The date. A build that was superseded weeks ago describes a user who has not restarted the browser in a long time. That is possible, but it is a minority, and a whole fleet of sessions pinned to the same old build is not a population.
  • The engine. Each build has a known V8 version and known behaviour, so the full version also has to fit what the page measures directly. See identifying the engine behind the user agent.
  • The other brands. fullVersionList repeats the version for the Chromium and Google Chrome brands next to a GREASE brand; they have to agree with each other and with the brand order Chrome generates for that major.

What follows for anyone setting a version

A browser that reports its own build number is automatically consistent with its engine, but it ages: every patch release Google ships moves the population away from it. A browser that reports a version it does not run has to pick one that exists for the claimed platform and track releases as they come out, and it has to keep the V8 behaviour consistent with the number.

There is no single right number. The safe choice is a build that shipped on the claimed platform recently and that real users still run in quantity, chosen per platform. The Chrome releases pages track stable builds and what changed between majors.

The through-line

The version looks like the simplest field in a fingerprint and turns out to depend on the platform, the date and the engine at once. That is the pattern across the whole fingerprint: no field stands alone, and the cheapest checks are the ones that compare a claim with public facts about what exists.

#fingerprinting#chromium#coherence#reference

Clearcote puts this into practice

An open-source Chromium with fingerprint control compiled into the engine. A drop-in for Playwright & Puppeteer.

  • 222engine patches
  • 34,478lines added
  • 330Chromium files changed
  • 354checks per build

Engine numbers are for the Pro build; the free open build is a smaller, public patch set.

Free for one browser with GitHub. No card.