Skip to content
Tech News
← Back to articles

Since Chromium 148, Math.tanh is now fingerprintable to link underlying OS

read original more articles

Math.tanh, every CSS trig function, and the Web Audio compressor all route through the host libm, so the rounding of a cosine betrays the OS a browser actually runs on. Where the leak lives across V8, Blink, and Web Audio, and what bit-for-bit reproduction of Apple's math library takes to close it.

Fingerprinting is usually about canvas, WebGL, fonts, audio. There is a quieter signal, and it lives in the last bits of a number.

Run this in any console:

Math . tanh ( 0.8 ) // 0.6640367702678491 genuine Linux Chrome (glibc) // 0.664036770267849 genuine macOS Chrome (libsystem_m) // 0.6640367702678489 genuine Windows Chrome (UCRT)

That output is an approximation, and its exact bits depend on the OS that computed it. A genuine Mac runs Math.tanh through Apple’s math library. Linux runs it through glibc. The two disagree on about a quarter of all inputs, usually by one unit in the last place (1 ULP). Windows, through the Universal C Runtime, disagrees with both on a few percent, and on the input above all three land on a different bit.

The same call, run on genuine Chrome 150 across three real machines:

Call Linux (glibc) macOS ( libsystem_m ) Windows (UCRT) Split Math.tanh(0.5) 0.46211715726000974 0.46211715726000974 0.46211715726000974 all three agree Math.tanh(0.7) 0.6043677771171636 0.6043677771171635 0.6043677771171635 Linux alone, 1 ULP Math.tanh(0.8) 0.6640367702678491 0.664036770267849 0.6640367702678489 all three differ, 2 ULP spread Math.tanh(0.9) 0.7162978701990245 0.7162978701990245 0.7162978701990244 Windows alone, 1 ULP

Measured over the DevTools protocol on Chrome 150: Linux (glibc), macOS 26 on Apple Silicon ( libsystem_m ), Windows 11 ( ucrtbase.dll ). tanh(0.5) is one of the roughly three-in-four inputs where everyone agrees, which is exactly why it makes a useless probe. tanh(0.8) is one that separates all three at once.

One tanh call on the right input is a per-OS signature. Claim macOS, return Linux math bits, and you have contradicted your own User-Agent.

This tell is recent. Until Chrome 148, V8 computed tanh itself with a bundled fdlibm port, so it returned the same bits on every OS and leaked nothing. V8 commit c1486295ae5 replaced it with std::tanh , which reads the host libm . It first shipped in V8 14.8.57, which is Chrome 148. Chrome 147 and earlier do not leak here. Chrome 148, 149, and 150 do.

... continue reading