PowerScan
ZH

指纹浏览器如何工作:完整的技术解析

指纹浏览器 · 阅读约 11 分钟 · 作者:PowerOps

图片:Unsplash

指纹面、一致的身份生成、磁盘上的存储隔离、按配置文件分流的网络,以及这套方法坦率的局限。

指纹浏览器做四件事:分别存储每个配置文件的浏览数据,控制每个配置文件所报告的设备身份,独立转发每个配置文件的流量,并让这三者长期保持一致。本文从机制层面逐一讲解每件事是怎么做到的,最后说明这套方法做不到什么。

指纹面

先看页面能读到什么,因为其余一切都是对此的回应。任何网站上的脚本都可以向浏览器提问,而答案描述的就是这台机器。这些指纹面可以自然地分成几组。

指纹面页面读取的内容
Navigator浏览器名称与版本、平台、语言列表、报告的处理器核数和内存、触控支持
屏幕宽度、高度、可用工作区、色深、设备像素比
Canvas在屏幕外绘制文字和图形所产生的确切像素,经哈希后得到稳定的值
WebGL图形厂商与渲染器字符串,以及渲染场景的哈希
音频振荡器输出经音频处理图后的结果,因软硬件栈不同而有差异
字体安装了哪些字体,通过文本测量推断得出
时区与时钟报告的时区和偏移量,并与流量到达的来源地对照
网络地址本身、WebRTC 眼中的连接候选,以及 TLS 握手的形态

没有哪一行能单独识别一台机器。识别靠的是组合,而谎言也恰恰在组合处被识破:无法属于同一台真实机器的数值,比任何单个数值都更扎眼。

采集既廉价又悄无声息。表中的每个值,任何页面都能通过公开文档的 API 获取,无需任何权限提示,而且大部分在访问的第一秒内就已到手。无论你对这种做法持什么立场,它都是现代网络的既定事实,也是指纹浏览器所要对抗的基线。

一致的身份是如何生成的

最朴素的做法是拦截每一个提问,然后把答案随机化。这行不通,原因在于结构:这些答案描述的是同一台机器,彼此相关,而各自独立的随机答案会破坏这种相关性。Windows 的 User-Agent 搭配只有 macOS 才自带的字体、任何笔记本都没出过的屏幕尺寸、从未与所声称平台共存过的图形字符串,每一种都是检测方能轻易验证的矛盾。

所以,一个真正可用的指纹浏览器是把身份当作一个整体来生成的。它从一类真实且常见的机器出发,所有数值都由这个选择推导而来。平台决定合理的字体列表、图形字符串和触控支持;屏幕取自这类机器实际出货的尺寸;语言和时区取自配置文件预期所在的地区。这些数值彼此吻合,因为它们是依据对同一台机器的同一份描述一起选定的。

第二个特性同样重要:这套数值是被保存下来的。它在配置文件创建时就写入其中,每次会话报告的都是相同的值,因为一台每次访问都在变的设备,描述的是没人拥有的硬件。稳定性,几乎就是“可信”的全部含义。

磁盘上的存储隔离

存储这件事最不起眼,却也最绝对。每个配置文件拥有一个目录,浏览器持久化的一切都在其中:Cookie 数据库、Local Storage、IndexedDB、HTTP 缓存、Service Worker 注册信息、扩展状态、历史记录和保存的凭据。两个配置文件就是两个互不相交的目录,每个运行中的浏览器都指向自己的那一个。

要检查的正是完全不相交这一点,因为部分隔离会悄悄失效。Cookie 很容易分开;缓存却能通过它保留的资源识别出回访的浏览器;Service Worker 可以保存标识符,并在两次访问之间持续运行;IndexedDB 则是现代应用存放它们真正信任的记录的地方。只覆盖了那几个有名的存储、却和其他存储共用的隔离,隔离的只是问题中看得见的那一部分。

持久化是另一半。会话会积累价值:已通过的安全验证、已建立的登录历史、回访者的行为轨迹。配置文件在会话之间保留它的目录,这才使账号操作成为可能。关闭时的写出让目录得以持久,这也是为什么在会话中途强行结束配置文件进程,可能会丢掉刚刚建立的会话。

网络路由

每个配置文件都带有自己的路由,在其浏览器启动时生效,所以流量会经由该配置文件的代理出去,而不触及系统设置或其他任何配置文件的路由。

路由也是最值得独立验证的部分,因为它是从第三方购买的。在分配之前先测试端点,并读取实际观察到的地址而不是宣传的地址,就能在问题还只是配置问题、尚未变成账号问题时将其发现。

浏览器自身改变了什么

工具改变页面所得答案的方式有两种,二者的区别是这个话题中最具技术性的分岔点。

方式工作原理弱点
脚本注入扩展或注入脚本覆盖页面调用的函数,使 Canvas 读取和 navigator 查询返回替换后的值覆盖本身是可见的。被打过补丁的函数可以被识别出打过补丁,而注入方遗漏的任何指纹面仍会返回真实值
在浏览器自身代码内部浏览器自己的实现,在产生真实值的代码路径上返回配置文件中保存的值构建和维护的工作量要大得多,这正是专门打造的工具有别于扩展的地方

注入方式是这个类别的起点,其天花板也早已为人所知:页面可以检查原生函数看上去是否仍然“原生”,还可以通过注入没有覆盖到的路径读取到同一个指纹面。因此,专门打造的指纹浏览器把改动做在浏览器内部,使得无论经由哪条路径读取,实现所报告的都是保存下来的身份。

打开一个配置文件究竟做了什么

  1. 加载保存的身份:一套一致的设备数值,与上次完全相同。
  2. 浏览器针对该配置文件自己的目录启动,因此每个持久化存储都属于这个配置文件。
  3. 应用路由:代理、经由代理的域名解析,以及受其约束的 WebRTC。
  4. 会话运行,在目录内积累状态。
  5. 关闭时将状态写出,这样下次打开就能延续同一台设备、同样的存储和同一条路由。

这份清单上的每一项,都可以从外部检查。打开指纹检测页面两次,比较两次之间的数值;查看磁盘上的配置文件目录;读取实际观察到的地址。这一类别的工具应当欢迎这样的检查,因为机制本身就是产品。

坦率的局限

这套方法有其边界,了解边界是称职使用的一部分。

请把这些局限当作定义来读,而不是当作失望。指纹浏览器是一件保持一致性的工具:独立的存储、稳定且可信的身份、与之匹配的路由,按配置文件整体维系,并在每次打开时原样重现。这就是全部机制,关于这个类别的其他一切说法,都不过是它的变体。

全部文章 · 开始扫描