Article de Scrapfly Engineering (12 juillet 2026) sur un canal de fingerprinting logé dans les derniers bits d'un nombre.

Le mécanisme. IEEE 754 définit le stockage d'un double mais n'exige pas l'arrondi correct des fonctions transcendantes. L'arrondi correct étant coûteux, chaque plateforme livre une libm avec ses propres coefficients minimax, tables et constantes. Conséquence : Math.tanh(0.8) rend trois valeurs distinctes selon glibc, libsystem_m et UCRT. Linux et macOS divergent sur environ un quart des entrées, généralement d'1 ULP. « A detector needs no math, only a table. » Et l'incohérence est immédiatement exploitable : annoncer macOS en rendant les bits de Linux contredit son propre User-Agent.

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.

**Scrapfly Engineering** — équipe d'ingénierie de **Scrapfly** , scrapfly.dev

Le tell est récent et daté. Jusqu'à Chrome 147, V8 calculait tanh avec un fdlibm embarqué, identique partout. Le commit c1486295ae5 l'a remplacé par std::tanh, qui lit la libm hôte, livré avec Chrome 148.

Trois surfaces fuient. Math.tanh est le seul Math.* concerné — V8 embarque et lie statiquement tout le reste. Les sept fonctions trigonométriques CSS fuient toutes, Blink appelant la libm hôte après une réduction d'angle en degrés qui ne partage pas le code de Math.sin. Et Web Audio touche trois bibliothèques dans un même graphe : Accelerate pour la FFT et les étages vectoriels, scalaire libsystem_m pour les transcendantes du compresseur. WASM, lui, ne fuit pas l'OS — seulement l'architecture.

Quatre pièges rendent la contre-mesure difficile : seule une partie des fonctions fuit, donc spoofer les autres crée une asymétrie détectable ; JavaScript et CSS sont des chemins de code séparés ; macOS embarque deux bibliothèques mathématiques qui divergent entre elles de 10 à 89 % selon la fonction, si bien que « reproduire la math d'Apple » n'a pas de sens tant qu'on ignore laquelle est appelée à quel site ; et ARM et x86 diffèrent sur la fusion multiplication-addition et la propagation des NaN.

Le bruit ne marche pas : il produit une valeur qui ne correspond à aucun OS réel, et sa non-déterminisme est elle-même un signal. La seule voie est la reproduction bit à bit — coefficients extraits de la libm cible et transcrits en hexadécimal, chaque fusion écrite en fma() explicite, compilation avec -ffp-contract=off.

L'éditeur déclare que ses billets sont rédigés avec l'aide de l'IA, les mécanismes, chiffres et code restant les siens.