Firefox 修了一个看起来很小、实际不轻的隐私漏洞。研究人员发现,indexedDB.databases() 在 Firefox/Gecko 里的返回顺序会泄露一个进程级稳定标识。结果是,不同网站能在同一浏览器进程运行期间,把你认成同一个人。

这事最扎眼的地方,不是网站读到了数据库内容,而是“不可关联”这层承诺被实现细节打穿了。好消息也很直接:Mozilla 已在 Firefox 150 和 ESR 140.10.0 修补,方法也够干脆,就是把结果规范化排序,去掉这份不该有的熵。

漏洞是什么,影响谁,现在修没修

问题出在 Firefox/Gecko 的 IndexedDB 实现,不是通用 Web 平台问题,也不是所有浏览器都中招。

研究人员的结论很明确:indexedDB.databases() 返回顺序会受到 Gecko 内部哈希/UUID 映射影响。这个映射是进程级的,不是站点级的。所以只要浏览器进程没彻底退出,不同站点就可能观察到同一个稳定模式。

受影响的重点对象有两类:

  • 使用 Firefox 隐私浏览的人
  • 使用 Tor Browser 的人

前者的问题是,私密窗口看着像新会话,但如果主进程还活着,可关联痕迹可能还在。后者的问题更敏感:Tor Browser 的 New Identity 目标就是切断前后会话关联,但这个 Gecko 同源缺陷会削弱这层边界。

修复状态已经明确:

项目情况
漏洞范围Firefox-based / Gecko 系实现
标识生命周期同一浏览器进程运行期间稳定,重启后变化
受影响产品Firefox 系浏览器,Tor Browser 受同源缺陷影响
修复版本Firefox 150、ESR 140.10.0
修复思路对返回结果做规范化/排序,去掉熵源

这里要卡住一个边界:这不是 Tor 网络层被攻破,也不是匿名路由失效。问题发生在本地浏览器实现层,后果是会话可关联性被削弱,而不是匿名网络本身被破解。

一个“无害 API”的返回顺序,为什么能变成指纹

根子并不玄。Firefox 在私密场景下不会直接用站点给的数据库名做底层标识,而是映射成 UUID,并存进 Gecko 的全局哈希表。这个映射活在进程里,不跟站点边界走。

麻烦出在下一步:indexedDB.databases() 取回数据库元数据时,没有先做稳定排序,而是把内部结构的遍历顺序直接暴露给网页。网页看不到你的数据库内容,却能看到“这台浏览器此刻内部是怎么排的”。这就够了。

研究人员给出的量化也说明问题不小。如果网站可控 16 个数据库名,理论上可提供约 44 bit 的指纹容量。现实里未必总能跑满,但对“同一进程里把前后访问串起来”已经够强。

这也是它对隐私模式和 Tor 特别致命的原因。普通追踪里,网站常靠 Cookie、LocalStorage、登录态。这里不一样。即使这些传统标识不用,单靠返回顺序,也可能把两段看似断开的访问重新缝上。

“千里之堤,溃于蚁穴”放在这里不算夸张。早期浏览器指纹抓字体、Canvas、缓存侧信道,套路都类似:不是偷敏感数据,而是偷实现留下的秩序。本案只是换成了 IndexedDB 的返回顺序。

真正暴露的,是浏览器隐私工程的老毛病

我更在意的,不是这个洞本身,而是它暴露出的工程习惯:浏览器内部状态,经常会在不经意间变成网页可观测信号。

这类问题最难防的地方,不在权限弹窗,也不在 API 名字听起来危险不危险。恰恰相反,很多洞都藏在“看起来很普通”的接口里。数据库顺序、缓存命中、计时差异、渲染细节,过去都出过事。今天换了一个入口,逻辑没变。

所以这事不能轻描淡写成“小 API 漏洞”。对追踪行业来说,只要能稳定关联,就够用了。对隐私产品来说,只要边界没有按承诺生效,信誉就会掉分。用户买的不是某个函数名安全,而是“这次新会话,真的和上次断开”。

Mozilla 这次反应倒是该给分。问题根子清楚,修法也直接:把结果排序,别让内部哈希顺序外泄。没有兜圈子,也没有把风险说轻。浏览器厂商能在这类实现级隐私问题上又快又准,并不常见。

对普通 Firefox 用户,动作很简单:确认自己是否已升级到 Firefox 150 或 ESR 140.10.0 及后续版本。没升级前,如果你把隐私模式当隔离边界,最稳妥的临时做法是彻底退出浏览器进程,而不是只关窗口。

对 Tor Browser 用户和依赖匿名隔离工作的群体,重点不是恐慌换工具,而是先看所用版本是否已纳入 Gecko 修复。如果还没有,New Identity 的隔离效果就不能按最理想情况理解,至少要把“彻底重启进程”当成更保守的做法。

接下来真正该观察的,不是这个洞会不会被说成世界末日。公开材料目前给的是可行性和机理,不是大规模在野利用数据。更该盯的是 Gecko 里还有没有同类接口,把内部状态继续漏成外部信号。修掉一个点不难,把它当成一类问题来清,才难。