Chromium 148 Math.tanh OS Fingerprinting Vulnerability
Chromium 148 Math.tanh OS Fingerprinting Vulnerability
Chromium 148 introduces OS-level fingerprinting via Math.tanh
Starting with Chromium 148, the Math.tanh function in V8 has become a fingerprintable signal that allows websites to identify a user's underlying operating system. This occurs because V8 replaced its bundled, portable fdlibm port with std::tanh, which calls the host operating system's native math library (libm).
Because different operating systems use different math libraries—glibc for Linux, libsystem_m for macOS, and UCRT for Windows—they produce slightly different approximations for transcendental functions. A single call to Math.tanh(0.8) can distinguish between these three platforms because they disagree on the final bits of the result (the Unit in the Last Place, or ULP).
OS-Specific Math Signatures
When running Math.tanh(0.8) in Chrome 150, the results differ across platforms:
- Linux (glibc):
0.6640367702678491 - macOS (libsystem_m):
0.664036770267849 - Windows (UCRT):
0.6640367702678489
This creates a contradiction for any browser spoofing its User-Agent. If a browser claims to be on macOS but returns Linux-specific math bits, anti-bot systems can immediately flag the session as fraudulent.
The Technical Root Cause: libm Divergence
IEEE 754 defines how floating-point numbers are stored, but it does not require functions like sin, cos, or tanh to be correctly rounded. Consequently, OS vendors implement their own libm libraries using different minimax coefficients, lookup tables, and reduction constants to balance speed and precision.
The V8 Change
Prior to Chrome 148, V8 used a bundled fdlibm implementation, ensuring identical results across all platforms. The transition to std::tanh in V8 commit c1486295ae5 shifted the computation to the host's libm, introducing the OS leak. While most Math.* functions in V8 remain bundled (via llvm-libc or dbl-64), Math.tanh is currently the only JavaScript math function that leaks the host OS.
Mapping the Fingerprinting Surface
Fingerprinting via math is not limited to Math.tanh. Different browser components route math calls through different libraries, creating multiple leak vectors:
| Operation | V8 Math.* (JS) |
CSS calc() |
Web Audio |
|---|---|---|---|
sin, cos, tan |
V8 bundled (Safe) | Host libm (Leaks) | Accelerate (Mac) / Scalar (Compressor) |
asin, acos, atan, atan2 |
V8 bundled (Safe) | Host libm (Leaks) | Not used |
tanh |
Host libm (Leaks) | None | Not used |
exp, log, pow |
V8 bundled (Safe) | Host libm (Leaks) | Scalar (Compressor) |
| Vector/FFT | N/A | N/A | Accelerate (Mac) |
Key Findings on Leak Surfaces
- CSS Trig Functions: All seven CSS trigonometric functions leak the OS because the Blink rendering engine calls the host
libmdirectly. - Web Audio (macOS): On Mac, Chrome uses Apple's Accelerate framework for FFT and vector math, but uses scalar
libsystem_mfor the DynamicsCompressor. This means a single audio graph can leak two different Apple math signatures. - WASM: WebAssembly math is generally identical across OSs because it bundles its own
libmor uses hardware-level arithmetic, though it can still leak CPU architecture (ARM vs x86) via NaN canonicalization.
Strategies for Mitigating Math Fingerprinting
Simple noise injection (adding random values to the output) is ineffective because it creates a result that matches no known OS and breaks determinism, which is itself a detectable signal.
Exact Algorithmic Reproduction
To successfully spoof an OS, the implementation must reproduce the target's libm exactly, including its specific minimax coefficients and rounding errors. This requires:
- Verbatim Coefficients: Copying the bit patterns of coefficients from the target library (e.g., Apple's
libsystem_m) rather than using decimal approximations. - FMA Control: Using explicit fused multiply-add (
fma()) calls and disabling compiler FMA contraction (-ffp-contract=off) to ensure the result is bit-identical across different CPU architectures (ARM vs x86).
Library Lifting
For Windows UCRT, it is possible to map the genuine ucrtbase.dll into a Linux process memory. This requires handling the Windows x64 ABI (using ms_abi in Clang) to avoid stack corruption and forcing the CPU-dispatch flag to the FMA path to match the results of modern Windows hardware.
Community Perspectives and Counterpoints
Discussion among technical observers highlights several nuances regarding this vulnerability:
"Recent glibc uses the correctly rounded tanh from CORE-MATH, so it returns different values than what's quoted in the article."
Some users noted that the vulnerability might be more useful for fingerprinting specific browser version ranges rather than just the OS, as most users do not spoof their User-Agent. Others argued that the ubiquity of fingerprinting vectors (IP, screen resolution, etc.) makes this specific leak a marginal addition to an already compromised privacy landscape.