指纹检测点: Math 数学库三角函数复合指纹

指纹检测点: Math 数学库三角函数复合指纹

检测了什么

在 iframe 的 window 上执行一条精心构造的三角函数复合表达式, 取 Math.atan2
的结果上报。一次采集同时探三层:

  1. JS 引擎数学库的数值指纹 —— sin / cos / sqrt / atan2 的浮点实现因引擎而异
    (不同 libm 移植、快速近似路径、常量折叠), 差异在多层复合运算里会放大显形,
    相当于"数学库版"的 canvas 指纹;
  2. iframe 环境是否健全 —— 表达式刻意跑在 iframe.contentWindow 的 Math 上,
    无头环境常见的 iframe 塌陷/全局共享异常会在这里暴露
    (比如 contentWindow 拿不到、Math 被主窗口代理后行为异常);
  3. 输出形态合理性 —— 结果掺了多个 Math.random() 噪声, 服务端无法精确复算,
    但可以校验值域(atan2 两正参 → 0~π/2)、有限小数位、非 NaN/Infinity 等"活体"特征。

检测代码(最小化)

// 注意: 在 iframe 的 window 上执行(A = iframe.contentWindow)
function mathProbe(A) {
  var Q = A.Math.SQRT2;
  var m = A.Math;

  var B = m.sqrt(m.abs(
        m.sin(m.PI / 90 * 100 - 40 * m.random() * (m.PI / 180) / 2)
      + m.cos(100 * Q * (m.PI / 180))
      * m.sin(m.PI / 180 * 40 - 100 * m.random() * (m.PI / 75) / 2)));

  var C = m.random() * m.sqrt(m.abs(
        1 - m.sin(40 * m.random() * (m.PI / 90) - 100 * Q * (m.PI / 180) / 2)
      + m.cos(3.7055555555555557)
      * m.random()
      * m.sin(m.PI / 180 * 60 - m.PI / 45 * 100 / 2)));

  return m.atan2(B, C);   // 上报这个角度
}

// 实际调用(采集脚本里):
//   var f = document.createElement("iframe");
//   document.body.appendChild(f);
//   report(mathProbe(f.contentWindow));

典型输出(每次不同):

0.5521227860182784
0.3875106984325592

这个点的特点

  • 掺噪声, 单值不可复算: 表达式里埋了 3 个 Math.random(), 输出每次会话必然
    不同 —— 服务端验不了"这个数应该等于多少", 只能验形态。伪造者容易犯的错反而是
    把值写死(每次一样)或给出 NaN;
  • 考的是"实现"而不是"结果": 真正的区分力藏在浮点末几位 —— 数学库不同的引擎
    算同一条表达式, 尾数会漂; 这类差异无法靠 mock Math 函数轻易糊弄(包一层 Math
    探针自己也能被检测到);
  • iframe 一石二鸟: 执行环境选在 iframe 里, 数学指纹和环境健全性一次拿到;
  • 和字体枚举、CSS calc 挑战应答同属"真浏览器证明"家族, 但实现最便宜:
    纯计算、零 DOM、零布局。
posted @ 2026-10-16 10:53  AngDH  阅读(4)  评论(0)    收藏  举报