网页无需授权即可读取屏幕尺寸、availHeight 与 devicePixelRatio。它们泄露什么、为何熵低,Tor letterboxing 如何遮蔽?
你打开的每个网页都能读取显示器有多大、操作系统留给页面多少空间,以及每个 CSS 像素背后有多少物理像素,整个过程无需任何权限弹窗。单独来看,这是一个常见的低熵值,但它是追踪者往更大指纹里添加的成本最低的信号之一,也是检测方最容易交叉核对的信号之一。
核心要点
- 网页无需提示即可读取
screen.width、screen.height、screen.availWidth、screen.availHeight、screen.colorDepth和window.devicePixelRatio。 availHeight通常小于height,因为任务栏、Dock 或菜单栏占用了空间;这个差值会暴露部分桌面布局。devicePixelRatio会随显示缩放和浏览器缩放变化,因此它描述的是你当前的配置,而不只是硬件。- 屏幕数值单独看熵很低。它们的意义在于与 GPU、字体和平台相乘,正如匿名集的计算所示。
- 防护手段的思路是把所有人归入少数几个“桶”:Tor Browser 的 letterboxing 与 Firefox 的 resist-fingerprinting 取整。
网页能读到什么
MDN 上的 Screen 接口列出了窗口所在显示器的属性。指纹识别中用到的有:
| 属性 | 报告内容 |
|---|---|
screen.width / screen.height | 屏幕尺寸(CSS 像素) |
screen.availWidth / screen.availHeight | 页面可用空间,已扣除任务栏等系统界面 |
screen.colorDepth | 每像素用于颜色的位数 |
window.devicePixelRatio | 物理像素与 CSS 像素之比 |
window.innerWidth / outerWidth(及高度) | 视口尺寸与整个浏览器窗口尺寸 |
窗口尺寸与屏幕属性一起定义在 W3C 的 CSSOM View Module 中。注意 width 和 height 以 CSS 像素计,而不是硬件像素。物理面板为 2880×1800、设备像素比为 2 的笔记本,通常会报告 1440×900。
可用尺寸为何不同于完整尺寸
MDN 的 availWidth 页面把该值描述为屏幕宽度减去所有常驻显示的用户界面元素(如任务栏);availHeight 同理。因此,若屏幕报告为 1920×1080 而 availHeight 为 1040,就说明约 40 像素高的区域被保留,可能是任务栏。自动隐藏的 Dock,或位于其他边缘的菜单栏,则会产生不同的数字。
这个差值是对桌面布局方式的一点真实泄露。两位用户即便显示器完全相同,也可能因任务栏大小、位置或自动隐藏设置而在此处不同。我们不在这里列出各操作系统的具体差值,因为它们会随系统版本和用户设置变化。
devicePixelRatio:缩放会透出来
MDN 的 devicePixelRatio 页面将其定义为当前显示设备上物理像素分辨率与 CSS 像素分辨率之比。有两件事会改变它:
- 显示缩放。 在系统设置中缩放为 150% 的 4K 显示器,与 100% 时报告的比值不同。
- 浏览器缩放。 在许多桌面浏览器上,缩放会改变该比值,因为它改变了覆盖一个 CSS 像素的设备像素数。MDN 指出缩放会影响该值,所以同一台机器的两次访问也可能不同。
因此它反映的是你当前的配置。它还能帮助区分高密度屏幕与普通屏幕上的浏览器,这是仅靠 screen.width 做不到的。
追踪者为何仍然想要它
1920×1080 的屏幕被极大比例的桌面用户共享,所以单看这个值,你只是身处很大的人群中。风险在于相乘:每个独立属性都会缩小人群,而屏幕几何与 GPU 渲染器、字体列表和时区相互独立。浏览器指纹识别指南列出了屏幕数据在各类信号中的位置,熵与匿名集则展示了少量低熵比特如何累加。
它还有两个追踪者喜欢的特性:它是被动的,不需要 API 探测或渲染测试,只需读取属性;它也廉价,瞬间完成,不会产生可见延迟。
异常值更显眼。罕见的显示器尺寸、自定义缩放带来的非整数比值,或任何标准显示器都不会产生的窗口尺寸,缩小人群的幅度远大于常见的 1080p 面板。移动端浏览器指纹识别介绍了像素比种类繁多的手机与桌面有何不同。
窗口尺寸是另一个信号
页面不仅能读取屏幕,还能读取视口和浏览器窗口的尺寸。它们会在你调整大小、贴靠或打开开发者工具时变化,因此更像是在标识一次会话,而不是一台设备。它们也会泄露一点上下文:视口比屏幕窄,说明窗口没有最大化。CSS 媒体查询指纹识别一文展示了相关路径:CSS 查询无需脚本读取 screen 就能暴露类似的几何信息。
多显示器与 Window Management API
有多台显示器时,基础的 screen 对象只描述窗口所在的那一台。Window Management API 旨在让页面获取所有已连接显示器的详情,并跨显示器放置窗口。MDN 将其描述为需要权限,因此它不像上述属性那样属于无提示信号。我们不声称哪些浏览器支持它;请到该页面的兼容性表中查看你的目标浏览器。
一致性角度
屏幕数值应与浏览器声称的设备相符。手机 UA 却报告 2560×1440 的屏幕且像素比为 1,就是不匹配;窗口比它所在的屏幕还大,同样如此。只改 UA 而忘记屏幕的自动化工具,恰恰会留下这种破绽。指纹一致性检查清单在七项检查中包含屏幕检查,hardwareConcurrency 与 deviceMemory则介绍了另一组可用于合理性比对的数值。
渲染几何是另一处交叉核对。通过脚本测量的页面元素取决于缩放,正如 ClientRects 指纹识别所解释的,声称的比值与测得的几何不符,设备伪装又多了一处可能露馅的地方。
防护:取整进桶
防护的目标是更大的人群,而不是随机伪造。
- Tor Browser 的 letterboxing。 Tor Browser 9.0 发布公告描述了把内容窗口取整为 200×100 像素的整数倍,使用户落入少数几个桶。Letterboxing 通过添加白色边距来应对调整大小和最大化,使窗口尽量接近期望尺寸,同时仍落在某个桶内。
- Firefox resist-fingerprinting。
privacy.resistFingerprinting借用了同样的取整思路。它改变什么、又会破坏什么,参见resist-fingerprinting 详解。
代价显而易见:页面周围有边距,布局略不精确。
BrowserInsight 实际做了什么
如实说明:指纹检测按浏览器的原样报告显示宽×高、设备像素比、色深和可用区域。机器人检测页面对屏幕尺寸做合理范围检查(宽 320 至 7680,高 480 至 4320)。当 UA 声称是移动设备时,它的开发者工具检测还会比较浏览器外部窗口尺寸与屏幕尺寸,因为两者相差很大通常意味着正在使用 DevTools 设备模拟。除此之外,它不会把屏幕数值与你的 UA 或 GPU 交叉比对。所有采集都在浏览器本地运行,不会向服务器发送任何内容。
常见问题
我的屏幕分辨率是唯一的吗? 单独来看很少如此。常见尺寸被许多人共用。只有与其他信号结合时才具备识别力。
为什么 availHeight 与 height 不同?
系统为任务栏或 Dock 等界面保留了空间,availHeight 将其排除。
浏览器缩放会改变屏幕尺寸吗?
它一定会改变 devicePixelRatio 和以 CSS 像素计的视口尺寸;报告的屏幕尺寸是否随之变化则取决于浏览器,所以别把 screen.width 当成不受缩放影响的值。
VPN 能隐藏屏幕分辨率吗? 不能。VPN 改变的是网络地址,而不是浏览器对其显示器的报告。
总结
屏幕尺寸、可用区域和像素比是细小的被动信号,无需权限,却能为任何指纹增加几个比特。它们更大的作用是作为对浏览器所声称设备的合理性检查。在指纹检测工具上查看你的浏览器报告了什么,并阅读浏览器指纹识别指南了解全貌。


