Your Browser Does Math Differently on Every OS, and Anti-Bot Systems Read the Bits
Articolo tecnico pubblicato il 12 luglio 2026 da Scrapfly Engineering, su un canale di fingerprinting del browser poco conosciuto: gli ultimi bit di un numero in virgola mobile tradiscono il sistema operativo. Il meccanismo: lo standard IEEE 754 definisce come viene memorizzato un double, ma non impone che sin, cos, tanh o exp siano correttamente arrotondati; ogni sistema distribuisce quindi una libm che scambia una frazione di ULP contro la velocità, con i propri coefficienti minimax, tabelle e costanti di riduzione.
Di **Scrapfly Engineering** — équipe d'ingénierie de **Scrapfly**// Fonte scrapfly.dev ↗/Lettura 2 min/.md// Traduzione verificata automaticamente
#fingerprinting#browser fingerprint#anti-bot#automation detection#IEEE 754#correct rounding#ULP#unit in the last place
Articolo di Scrapfly Engineering (12 luglio 2026) su un canale di fingerprinting annidato negli ultimi bit di un numero.
Il meccanismo. Lo standard IEEE 754 definisce come viene memorizzato un double ma non impone l'arrotondamento corretto delle funzioni trascendenti. Poiché l'arrotondamento corretto è costoso, ogni piattaforma distribuisce una libm con i propri coefficienti minimax, tabelle e costanti. Ne risulta che Math.tanh(0.8) restituisce tre valori distinti a seconda di glibc, libsystem_m e UCRT. Linux e macOS divergono su circa un quarto degli input, tipicamente di 1 ULP. « Un rilevatore non ha bisogno di matematica, solo di una tabella. » E l'incoerenza è immediatamente sfruttabile: dichiarare macOS restituendo bit di Linux contraddice il proprio User-Agent.
una singola chiamata a tanh sull'input giusto è una firma per-OS. Dichiara macOS, restituisci bit matematici di Linux, e hai contraddetto il tuo stesso User-Agent.
— **Scrapfly Engineering** — équipe d'ingénierie de **Scrapfly** , scrapfly.dev
L'indizio è recente e datato. Fino a Chrome 147, V8 calcolava tanh con una fdlibm integrata, identica ovunque. Il commit c1486295ae5 l'ha sostituita con std::tanh, che legge la libm dell'host, distribuito con Chrome 148.
Tre superfici presentano fughe.Math.tanh è l'unica funzione Math.* interessata — V8 integra e collega staticamente tutto il resto. Tutte le sette funzioni trigonometriche CSS presentano fughe, con Blink che chiama la libm dell'host dopo una riduzione dell'angolo in gradi che non condivide codice con Math.sin. E Web Audio coinvolge tre librerie all'interno di un singolo grafo: Accelerate per le fasi FFT e vettoriali, libsystem_m scalare per le funzioni trascendenti del compressore. WASM, invece, non presenta fughe relative al sistema operativo — solo all'architettura.
Quattro trappole rendono difficile la contromisura: solo alcune funzioni presentano la fuga, quindi falsificare le altre crea un'asimmetria rilevabile; JavaScript e CSS sono percorsi di codice separati; macOS integra due librerie matematiche che divergono tra loro dal 10 all'89% a seconda della funzione, per cui "riprodurre la matematica di Apple" non ha senso finché non si sa quale venga chiamata in quale punto; e ARM e x86 differiscono su fused multiply-add e propagazione di NaN.
Il rumore non funziona: produce un valore che non corrisponde a nessun OS reale, e il suo non-determinismo è a sua volta un segnale. L'unica via è la riproduzione bit a bit — coefficienti estratti dalla libm target e trascritti in esadecimale, ogni fusione scritta come fma() esplicito, compilata con -ffp-contract=off.
L'editore dichiara che i propri post sono redatti con l'assistenza dell'IA, mentre i meccanismi, i dati e il codice restano propri.
Punti chiave
Il principio, in una riga. IEEE 754 impone la memorizzazione di un double, non l'arrotondamento corretto delle funzioni trascendenti. L'arrotondamento corretto è costoso, quindi ogni sistema distribuisce la propria libm con i propri coefficienti minimax, tabelle e costanti di riduzione. La differenza di arrotondamento è una firma.
La sonda, utile da conoscere.Math.tanh(0.8) restituisce 0.6640367702678491 su Linux (glibc), 0.664036770267849 su macOS (libsystem_m) e 0.6640367702678489 su Windows (UCRT) — tutti e tre differiscono, di 2 ULP. Linux e macOS divergono su circa un quarto di tutti gli input, tipicamente di 1 ULP; Windows diverge da entrambi su qualche punto percentuale. → « Un rilevatore non ha bisogno di matematica, solo di una tabella. »
L'indizio è datato fino al commit, ed è ciò che rende l'articolo utile. fino a Chrome 147, V8 calcolava tanh con una porta fdlibm integrata — stessi bit ovunque, nessuna fuga. Il commit V8 c1486295ae5 l'ha sostituita con std::tanh, che legge la libm dell'host; distribuito in V8 14.8.57 = Chrome 148. 148, 149, 150 presentano la fuga. 147 e le versioni precedenti no. → Una regressione della privacy introdotta da una scelta di implementazione ordinaria, e una finestra di versioni precisa per datare un'impronta.
La mappa delle fughe — la parte più riutilizzabile. | Operazione | Math. (JS) | CSS calc() | Web Audio | |---|---|---|---| | sin cos tan | V8 integrata | libm dell'host | Accelerate (FFT), scalare nel compressore | | asin acos atan atan2 | V8 integrata | libm dell'host | non utilizzata | | tanh | libm dell'host | — | non utilizzata | | exp, log, pow | V8 integrata | libm dell'host | scalare nel compressore | | vettoriale, FFT | — | — | Accelerate (vDSP) su Mac | | sqrt, aritmetica | hardware | hardware | hardware | → V8 instrada quasi tutto attraverso la propria matematica integrata: JavaScript presenta una fuga in un solo punto, Math.tanh. Il CSS presenta fughe ovunque. Web Audio coinvolge tre librerie all'interno di un singolo grafo.
WASM non presenta fughe relative al sistema operativo. nessun opcode trascendente, sin proviene da qualunque libm il modulo abbia integrato, e l'aritmetica (f64.sqrt, f64.mul) è basata sull'hardware. Il suo unico asse di fingerprinting è ARM contro x86 (canonicalizzazione di NaN, alcune differenze di arrotondamento SIMD).
Le quattro trappole — la vera lezione di progettazione, trasferibile ben oltre questo argomento. 1. Solo alcune funzioni presentano la fuga. Falsificare le funzioni che non presentano la fuga crea un'incoerenza, e « quell'asimmetria è essa stessa verificabile. » → Sovracorreggere è rilevabile quanto sottocorreggere. 2. JS e CSS sono percorsi di codice distinti. Le funzioni trigonometriche CSS riducono l'angolo in gradi poi chiamano std::sin sul valore ridotto — un risultato diverso da un sin() in radianti. Il team ha riprodotto « la riduzione in gradi e il passaggio da radianti a gradi bit a bit, non solo la funzione foglia. » 3. macOS ha due librerie matematiche che si contraddicono a vicenda. La libsystem_m scalare e le routine vettoriali di Accelerate divergono dal 10 all'89% degli input a seconda della funzione. cos(0): 1.0 in scalare, 0.9999999999999999 in Accelerate. → « "Riprodurre la matematica di Apple" resta indefinito finché non si sa quale libreria il browser chiami, e in quale punto. » Risposta stabilita sperimentalmente: scalare per Math.tanh, trigonometria CSS e le funzioni trascendenti per-campione del compressore; Accelerate per il DSP di Web Audio (FFT, matematica vettoriale, filtri biquad). Scegliere la libreria sbagliata costa 1 ULP sulla maggior parte degli input — peggio che non fare nulla. 4. Anche l'architettura presenta una fuga. ARM e x86 differiscono sul fused multiply-add e sulla propagazione del segno di NaN; una riproduzione corretta sulla carta va alla deriva se il compilatore fonde le operazioni da un lato e non dall'altro.
Perché il rumore non funziona — un argomento generalizzabile a qualunque contromisura di fingerprinting.« Perturbare l'output fallisce due volte. Un confronto di riferimento vede un valore che non corrisponde a nessun OS reale, e la casualità a ogni chiamata rompe il determinismo, che è essa stessa un indizio. » → Una difesa che produce un valore impossibile è identificativa tanto quanto un valore vero. L'obiettivo non è "il rumore", è il valore esatto del sistema dichiarato.
La contromisura scelta, e i suoi tre requisiti. (1) recuperare i coefficienti minimax, le tabelle degli esponenti e le costanti di riduzione della libm target e trascriverli in C portabile; (2) copiare i pattern di bit in esadecimale — « una trascrizione decimale arrotonderebbe in modo diverso »; (3) scrivere ogni fusione come fma() esplicito e compilare con -ffp-contract=off, affinché le operazioni fuse siano esattamente quelle che Apple fonde e il risultato sia identico su CPU con e senza FMA, e tra la macchina ARM emulata e la flotta x86 che esegue l'operazione. Quando la riproduzione non vale lo sforzo: « riprendere l'originale » — poiché Windows UCRT è x86-64 e a codice indipendente dalla posizione.
Ciò che l'articolo implica per gli agenti che navigano. — non dichiarato nel testo, ma diretto: un agente che guida un browser per leggere il web attraversa esattamente questi controlli. Gli harness che escalano al browser reale dell'utente invece di imitarne uno (cfr. il percorso browser di [[skill-gibbs-hyperresearch-2026-08-03]], che guida il vero Chrome autenticato e pone come confine rigido che « CAPTCHA, 2FA e login non vengono mai risolti automaticamente ») aggirano il problema per costruzione: non c'è nulla da falsificare quando il browser è realmente ciò che dichiara di essere. Due strategie opposte di fronte allo stesso muro.
Inquadramento d'uso. l'articolo documenta una tecnica di elusione del rilevamento, scritta da un fornitore di web scraping. È utilizzabile in modo difensivo (capire cosa legga realmente il proprio sistema anti-bot, e sapere che un singolo segnale Math.tanh isolato data il browser tanto quanto identifica l'OS) così come per l'elusione. Il testo non affronta il consenso dei siti sottoposti a scraping, né i termini di servizio — ciò esula dal suo ambito dichiarato.
Redazione assistita dall'IA, dichiarata.« i post qui presenti sono redatti con l'IA… I meccanismi, i dati e il codice sono nostri. » Una dichiarazione onesta e rara, degna di nota quando si cita il testo come fonte primaria. Le misurazioni sono accompagnate dal loro protocollo (protocollo DevTools, tre macchine nominate con le rispettive versioni), il che le rende verificabili in modo indipendente a prescindere da come sia stata prodotta la prosa.
Meta / correlati. sugli agenti che guidano il browser, [[skill-gibbs-hyperresearch-2026-08-03]] (percorso browser, escalation, confine CAPTCHA); sulla superficie d'attacco e i contenuti web trattati come dati ostili, [[valente-zalewski-beyond-zero-enterprise-security-ai-era-2026-07-20]]; sui browser IA e l'automazione, [[mody-browser-company-arc-dia-ai-native-2025-11-23]], perplexity-chrome-integration-browser-ai-search-2025-10-22, e mcp-replaces-browser-logrocket-2025-09-15.
Dati chiave
trois valeurs distinctes sur glibc, libsystem_m et UCRT pour l'entrée 0.8