Skip to main content

Browser fingerprinting has long been a cat-and-mouse game between privacy advocates and tracking systems. Canvas fingerprinting, WebGL renderer strings, audio context quirks — web developers have grown familiar with the usual suspects. But a change shipped quietly in Chromium 148 has opened an entirely new fingerprinting surface, and it sits in the last place most developers would think to look: floating-point arithmetic.

A single function call — Math.tanh(0.8) — now returns a different value depending on whether your browser is running on Linux, macOS, or Windows. And that tiny difference, buried in the 16th decimal place, is enough to unmask your operating system from JavaScript alone.

TL;DR

  • Chromium 148 replaced V8’s bundled fdlibm math library with the host OS’s native std::tanh, exposing OS-specific floating-point results to JavaScript
  • Different operating systems (Linux/glibc, macOS/libsystem_m, Windows/UCRT) return subtly different results for transcendental math functions, differing by 1–2 ULP (units in the last place)
  • This creates a passive, deterministic fingerprinting vector requiring just a single line of JavaScript — no canvas, no WebGL, no permissions
  • The leak extends beyond Math.tanh to CSS trigonometric functions and Web Audio internals, creating multiple correlated fingerprinting surfaces
  • Anti-bot and fraud detection systems are already using math-based OS signatures to detect browser spoofing — development teams building privacy-sensitive applications need to understand the implications

What Changed — and Why It Matters

Prior to Chromium 148, V8 used fdlibm — a bundled, platform-independent math library — to compute transcendental functions like Math.tanh, Math.sin, and Math.cos. This meant every Chrome installation, regardless of operating system, returned identical results for the same inputs. The maths was deterministic and cross-platform.

That changed with V8 commit c1486295ae5, which replaced fdlibm with std::tanh from the host system’s native C math library (libm). The motivation was straightforward: native implementations are faster, and they leverage CPU-specific optimisations that a bundled library cannot.

The unintended consequence? JavaScript’s Math.tanh now reads the host libm, and different operating systems ship different math libraries:

  • Linux uses glibc
  • macOS uses Apple’s libsystem_m
  • Windows uses UCRT (ucrtbase.dll)

Each library implements IEEE 754 transcendental functions with different minimax polynomial coefficients and lookup tables. They are all mathematically correct — but they diverge in the last binary digits on roughly 25% of inputs.

The Numbers Tell the Story

Call Math.tanh(0.8) across the three major platforms and you get:

  • Linux: 0.6640367702678491
  • macOS: 0.664036770267849
  • Windows: 0.6640367702678489

The differences are 1–2 ULP (units in the last place) — invisible to human eyes, but trivially detectable by a script. A single function call on a carefully chosen input is enough to distinguish your operating system with near-perfect accuracy.

No permission prompts. No canvas rendering. No WebGL queries. Just arithmetic.

It Goes Deeper Than Math.tanh

If this were limited to a single JavaScript function, the impact would be contained. It is not.

CSS trigonometric functionssin(), cos(), tan(), asin(), acos(), atan(), atan2() — call the host libm directly through Blink’s layout engine. Any CSS property that uses these functions (think calc() expressions involving trigonometry) can leak OS information without a single line of JavaScript running.

Web Audio’s DynamicsCompressor on macOS uses libsystem_m for per-sample transcendentals, whilst its FFT implementation calls into Apple’s Accelerate framework. This introduces multiple correlated fingerprinting surfaces within a single AudioContext.

The attack surface is not one function — it is the entire mathematical foundation of the browser’s rendering, scripting, and audio stacks.

Why Anti-Bot Systems Are Already Exploiting This

For fraud detection and anti-bot platforms, this is a gift. Browser spoofing — where a headless browser or automation tool claims to be running on macOS whilst actually executing on a Linux server — has long been a challenge to detect reliably. User-Agent strings are trivially forged.

Math-based OS fingerprinting changes the equation entirely. A browser claiming to be Safari on macOS but returning Linux-flavoured Math.tanh results is immediately exposed. The math bits cannot lie — they come directly from the compiled native library on the host machine.

Anti-bot vendors are now using these signatures as consistency checks, cross-referencing math results against declared browser identity. It is deterministic, session-persistent, and nearly impossible to spoof without bit-perfect reproduction of the target platform’s libm implementation.

The Mitigation Challenge

For privacy-focused browsers and tools, closing this leak is far harder than it appears. A proper fix requires:

  • Bit-perfect reproduction of each target platform’s libm using extracted minimax polynomial coefficients
  • Deterministic compilation with careful control of fused-multiply-add (FMA) instructions, which vary across CPU architectures
  • Patching three separate code paths — V8 (JavaScript), Blink (CSS), and Web Audio — each with different entry points to the host math library
  • Regression testing against 871,000+ inputs per release to validate results match real hardware

This is not a configuration toggle. It is a substantial engineering effort that most browser forks and privacy tools have not yet undertaken.

What This Means for Development Teams

If your application handles sensitive user data, operates in privacy-regulated markets, or serves users who may be at risk from tracking, this matters.

Audit your fingerprinting exposure

Review whether your application — or any third-party scripts you load — calls transcendental math functions or CSS trigonometric expressions. These are now potential data leakage vectors.

Understand the cross-browser landscape

Firefox still uses a bundled fdlibm implementation, meaning it returns consistent cross-platform results. Safari’s behaviour depends on the macOS version. Chromium-based browsers (Chrome, Edge, Brave, Arc) are all affected. The fingerprinting vector is browser-engine-specific, not universal.

Reconsider your privacy threat model

If your threat model accounts for canvas fingerprinting but not math fingerprinting, it is incomplete. The maths-based approach is harder to detect (no visual rendering), harder to block (no obvious API to restrict), and harder to spoof (requires platform-specific compiled code).

Watch for compounding signals

Fingerprinters rarely rely on a single signal. Math-based OS detection becomes most powerful when combined with timing analysis, font enumeration, and GPU signatures. Each additional signal narrows the anonymity set. Development teams building anti-fingerprinting protections need to think in terms of signal correlation, not individual vectors.

The Bigger Picture: Performance vs Privacy

The Chromium team’s decision to use native libm was a reasonable performance optimisation. Native math libraries are faster, and for 99% of web applications, the rounding differences are mathematically irrelevant.

But this case illustrates a tension that runs through modern browser engineering: every performance optimisation that touches platform-specific code paths is a potential privacy leak. The browser is an abstraction layer, and when that abstraction becomes transparent — when JavaScript can observe the host system’s behaviour through return values — the privacy model erodes.

This is not a new pattern. We have seen it with canvas rendering (GPU-specific), Web Audio (hardware-specific), and WebGL (driver-specific). Math fingerprinting is simply the latest — and arguably most elegant — example of the same fundamental trade-off.

What Comes Next

The W3C’s Privacy Interest Group has flagged math-based fingerprinting as an area requiring specification-level guidance. Whether Chromium reverts to fdlibm for transcendentals, adds a quantisation layer, or accepts the trade-off remains to be seen.

For development teams, the immediate action is awareness. If you are building applications where user privacy is a selling point — or a regulatory requirement — this is a vector you need to account for. And if you are relying on browser-level privacy protections to shield your users, understand that those protections now have a mathematical blind spot.

At REPTILEHAUS, we help teams build web applications with security and privacy baked in from the architecture level — not bolted on as an afterthought. If your team needs guidance on fingerprinting defences, privacy-by-design architecture, or security auditing for production applications, get in touch.

📷 Photo by George Prentzas on Unsplash