← 返回信息流
AI 资讯Hacker News·1 小时前

Chronium 148起Math.tanh可被用于指纹识别关联操作系统

原标题:Since Chronium 148, Math.tanh is now fingerprintable to link underlying OS

速览

Chronium 148版本开始,Math.tanh函数的实现方式发生了变化,使得该函数可以被用于浏览器指纹识别技术。攻击者或追踪者可以通过测试Math.tanh的返回值差异来推断用户底层操作系统的类型。这增加了用户隐私泄露的风险,尤其是跨平台指纹识别能力得到增强。

AI 深度解读

背景

自 Chrome 148 起,Math.tanh 成为可指纹化的新通道,能够泄露底层操作系统信息。这一发现来自 Hacker News 的一篇技术分析文章,揭示了浏览器在不同操作系统上执行数学运算时存在微小差异,反机器人系统可以利用这些差异来识别用户真实的 OS。此前,指纹识别主要依赖 Canvas、WebGL、字体、音频等传统信号,而数学运算的末位比特差异是一条更隐蔽的信号。

核心内容

在任意浏览器控制台中运行 Math.tanh(0.8),会得到以下结果(以 Chrome 148+ 为例):

  • Linux Chrome(glibc):0.6640367702678491
  • macOS Chrome(libsystem_m):0.664036770267849
  • Windows Chrome(UCRT):0.6640367702678489

这不是一个常数。Math.tanh 是一个近似计算,其精确比特位取决于执行它的操作系统。macOS 通过 Apple 的数学库计算,Linux 通过 glibc 计算,两者在约四分之一的输入上存在分歧,通常相差一个 ULP(末位单位)。Windows 通过 Universal C Runtime(UCRT)计算,与两者在少数输入上不同。上述输入 0.8 恰好使三个系统落在不同的比特位上。

同样的调用,在真实的 Chrome 150 上,通过 DevTools 协议测量三台真实机器(Linux glibc、macOS Apple Silicon libsystem_m、Windows 11 ucrtbase.dll),tanh(0.5) 是约四分之三的输入中所有系统一致的地方,因此无法作为探测信号。而 tanh(0.8) 则能同时区分三者。一个正确的 tanh 调用输入,就是一个 OS 签名。声称是 macOS,却返回 Linux 的数学比特位,就会与 User-Agent 矛盾。

这一泄漏是近期才出现的。在 Chrome 148 之前,V8 使用自带的 fdlibm 移植版计算 tanh,因此所有 OS 返回相同比特位,不泄漏任何信息。V8 提交 c1486295ae5 将其替换为 std::tanh,从而读取宿主 libm。该改动首次随 V8 14.8.57 发布,对应 Chrome 148。Chrome 147 及更早版本不泄漏,Chrome 148、149、150 均泄漏。

Scrapfly 开发了一个浏览器,需要在数百个信号上匹配真实浏览器,数学处理是其中最困难之一。以下阐述原因及如何应对。

为什么同一个函数返回不同比特位

IEEE 754 定义了 double 的存储方式,但未要求 sincostanhexp 等函数必须正确舍入。正确舍入成本高昂,因此每个供应商都提供自己的 libm,在速度与精度之间权衡,使用各自的极小极大系数、查找表和规约常量。三种实现(Linux glibc、macOS Apple libsystem_m、Windows UCRT)在绝大多数输入上一致,但在足够多的输入上分裂,足以区分 OS。检测器无需数学,只需要一张对照表:真实 macOS Chrome 返回 cos(1) 的某种模式,真实 Linux Chrome 返回另一种。一次探测,一次对比即可。

四个陷阱

  1. 只有部分数学函数泄漏。V8 自带数学库并静态链接:Math.expMath.powMath.atan 等来自捆绑的 llvm-libc,Math.sin/Math.cos 来自捆绑的 glibc 派生的 dbl-64 例程,在所有 OS 上完全相同。因此要伪造这些函数会产生不一致。例外是 Math.tanh:自 Chrome 148 起,V8 使用平台 std::tanh 而非之前的捆绑例程,因此读取宿主 libm,这是唯一泄漏 OS 的 Math.*,这种不对称性本身也可被检测。

  2. JavaScript 数学与 CSS 数学走不同代码路径。CSS sin()cos()atan2() 不共享 Math.sin 的代码。布局引擎先将角度转换为度数,然后调用平台 std::sin 处理规约后的值,这会产生与直接弧度 sin() 不同的结果,且命中宿主 libm,因此所有七个 CSS 三角函数都会泄漏。需要比特级精确地重现度数规约和弧度到度数的步骤,而不仅仅是底层函数。

  3. macOS 有两个数学库,结果不一致。Apple Silicon 同时提供标量 libsystem_m 和 Accelerate 框架的向量例程(如 vvsinvvtanh),它们是不同的代码。在百万个输入上,它们分歧的比例从 10% 到 89% 不等,取决于函数。例如 cos(0):标量返回精确的 1.0,Accelerate 返回 0.9999999999999999。因此“重现 Apple 的数学”在知道浏览器调用哪个库、在哪个调用点之前是未定义的。通过真实的 Mac 上运行真实 Chrome,通过调试协议读取精确的 double,确定:Math.tanh、CSS 三角函数以及音频压缩器的逐样本超越函数由标量 libsystem_m 支持;Accelerate 支持 Mac 上 Chrome 的 Web Audio DSP(FFT、向量数学、双二阶滤波器)。为错误的调用点选择错误的库,多数输入上会差 1 ULP,比不伪造更糟。

  4. 架构也会泄漏。ARM 和 x86 在融合乘加(FMA)和 NaN 符号传播上存在差异。如果编译器在一个目标上融合了乘加而在另一个目标上没有,再现结果就会偏移。

映射:什么泄漏在哪里

下表总结了路由路径。加粗表示宿主 libm(glibc、Apple libsystem_m、UCRT),即泄漏 OS 的代码。其余部分在所有机器上相同,可安全保留。

| 组件 | 函数/路径 | 使用哪个库 | |------|----------|------------| | V8 捆绑 | 大部分 Math.*(exp, pow, atan, sin/cos 等) | 静态链接(llvm-libc 或 glibc 派生),所有 OS 相同 | | V8 宿主 | Math.tanh | 宿主 libm | | CSS 三角函数 | sin(), cos(), atan2() 等 (角度制规约 → 平台 std::sin 等) | 宿主 libm | | Web Audio(Mac) | FFT、向量阶段(fft_frame_mac.cc, vector_math_mac.h, biquad.cc) | Accelerate(vDSP) | | Web Audio(Mac) | DynamicsCompressor 的逐样本超越函数 | 标量 libsystem_m | | Web Audio(非 Mac) | 全部 | 宿主 libm(Linux glibc / Windows UCRT) | | WASM | 无超越函数操作码,sin 等来自模块捆绑的 libm,算术(f64.sqrt, f64.mul)是硬件 | 硬件 + 捆绑 libm,所有 OS 相同,仅 ARM vs x86 在 NaN 规范化上有差异 |

三个关键泄漏面:Math.tanh、所有 CSS 三角函数

查看原文 →scrapfly.dev