Hacker News Best

Fingerprints are the new cookies

8.5内容质量

TL;DR · AI 摘要

浏览器指纹技术正在取代Cookie,成为广告和数据收集的新手段,Google通过三阶段策略应对隐私挑战。

核心要点

  • 指纹技术通过设备特征识别用户,比Cookie更难以清除
  • Google在2019年承诺淘汰Cookie,但转向指纹技术以维持广告业务
  • Privacy Sandbox方案因效果不佳未被广泛采用

结构提纲

按章节快速跳转。

  1. 揭示浏览器指纹技术正在取代Cookie成为数据收集新手段

  2. 通过设备特征识别用户,比Cookie更难以清除

  3. ›Google策略演变

    分三阶段应对隐私挑战:压力、分散注意力、加速指纹技术应用

  4. 欧盟法规推动技术变革但Google方案未被广泛采用

  5. 指纹技术存在可被反制的潜在漏洞

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 浏览器指纹技术
    • 工作原理
      • 设备特征识别
    • Google策略
      • 三阶段演变
      • Privacy Sandbox
    • 隐私影响
      • 数据收集新手段
      • 欧盟法规应对

金句 / Highlights

值得收藏与分享的关键句。

#隐私保护#浏览器指纹#Google#广告技术
打开原文

指纹将成为新的 Cookie

从现在开始,我将称呼你为:

……

计算中……

尝试刷新页面。清除 Cookie。连接到 VPN。

你仍然是那个……

现在在手机或其他设备上打开它,你的昵称将不同,但同样具有一致性。

在无痕模式下是否不同?很好。但始终相同?坏消息。

想象一下:

你访问的大多数网站都会因展示广告而获得报酬,并间接运行我的脚本,让我知道你是那个……。我可以利用它来决定你将看到哪些广告。但更重要的是,如果你在该网站上创建了账户,我可以出钱购买你的数据——无论他们隐私政策允许分享什么:你的姓名、活动记录、与 AI 的对话……

不久之后,我对你的了解可能超过你的朋友,甚至可能超过你对自己的了解。

“那又怎样?”——你说。

“我没有什么可隐藏的。而且我更喜欢看到相关的广告……有时它们正好显示我需要的东西!而且数据已经被匿名化了……”

你看,问题其实根本不在于你。现在甚至也不再真正关乎广告。没人关心你。如果警察或政府恰好关心,我也乐意接受他们的钱。

我查看所有这些数据时,看到的不是人。我看到的是模式。模式中涌现出的模式。经济、社会和人类心理的活生生的数字分形状态。21 世纪的水晶球,它由硅制成!这就是产品。

而它将流向出价最高的人!

那么,你又是什么?一个齿轮?一头牛?一名志愿者?

还记得关于第三方 Cookie 的巨大争议吗?当时争议如此之大,以至于欧盟已经推出了其最伟大的发明之一——同意横幅。

如果欧盟的行动速度超过科技公司,那只能说明科技公司正在按兵不动。而其中一家科技公司恰好掌控着三分之二的浏览器市场份额。

当时的策略是什么?

让我们为谷歌鼓掌——地球上最大的广告公司!

第一幕:施压 —— “隐私对我们来说至关重要,我们所做的每一件事都如此。”

2019 年,Cookie 仍然炙手可热。它已成为糟糕的公关话题,Safari 和 Firefox 已经开始阻止它们。

一年后,谷歌承诺:我们将摧毁 Cookie!!并建立一个以隐私为先的新时代。

第二幕:转移注意力 —— “与其淘汰第三方 Cookie,我们宁愿引入一种新体验。”

五年后:人们现在担忧的事情远比 Cookie 严重得多,而谷歌开发的解决方案(隐私沙盒)效果一般,还引发了反垄断担忧,没人使用它们。

“你知道吗,让我们继续使用 Cookie 吧。不过我们会屏蔽你的 IP 地址*!”(*但仅在无痕模式且已认证时)(**最终他们甚至没有兑现这个承诺)

第三幕:加速 —— 现在你可以在我们的广告产品中使用设备指纹识别!

现在有一种更好的方式来识别谁是谁!

指纹识别是如何工作的?

我们已经在保障浏览安全方面取得了大量文明进步。过去那种仅仅访问网站就可能感染病毒的担忧早已成为历史。但需要明确的是,安全性的定义因人而异。各方普遍认同的安全边界仅限于隔离原则:一个网站的代码无法访问其他网站存储的数据,且在未获得授权时无法查看你的文件或应用程序。Chrome 和 Edge 的安全措施止步于此。而 Safari(尤其是 iOS/macOS 26+ 版本)和 Firefox 则将安全定义扩展至隐私保护领域,但它们仍无法完全防止指纹识别。Brave 和 Tor 是以隐私为核心的设计理念的浏览器,新兴的 Mullvad Browser(在我看来,Mullvad 是目前最优秀的VPN服务提供商之一)也正在加入这一行列。

代码在你的硬件上运行,这些硬件可以通过某些方式被测量,从而产生一致且独特的读数。实际上对此几乎无能为力,因此目前只有两种成熟解决方案:

  • 在适当位置注入少量噪声。这种技术被称为“模糊化”(farbling),Brave 正是通过这种方式使你的指纹变得不一致。
  • 让所有设备看起来完全相同,从而无法区分浏览器用户。Tor 和 Mullvad 采用的就是这种方案。

好的,让我们来创建一个指纹

构成你指纹的数据来源有两个:网络请求和代码运行环境。

从网络角度来看,数据通常要么脆弱,要么通用:

  • IP 地址;在理想情况下如果一个人始终使用相同的 IP 地址,它可能是唯一需要的数据。但现实中人们经常在移动网络上浏览,共享WiFi,使用VPN,或者ISP会轮换家庭网络的IP地址。因此IP地址是脆弱的。
  • 请求头信息如 User-Agent 或 Accept-Language;会暴露你的浏览器、操作系统、版本和语言设置。

当设备可以执行代码时,你可以无需任何权限提示就测量其硬件特性,这些数据出人意料地稳定:

  • GPU;行为特征、厂商、驱动程序
  • CPU;行为特征、厂商、线程数量
  • 内存容量
  • 显示器数据;分辨率、像素比、刷新率
  • 音频处理能力
  • 设备型号

在软件层面还包括:已安装字体、扩展程序、系统信息等。

数以百万计的设备都使用最新版 Chrome,数以百万计的 Mac 电脑搭载 M4 芯片,还有数以百万计的浏览器使用法语。

但当你查看同时运行最新版法语 Chrome 的 M4 芯片设备时,这个数量会显著下降。再加上硬件测量数据后,这个数量会变得如此之低,几乎可以视为唯一。

指纹不需要真正全球唯一——只要在你的样本范围内足够独特即可。

一个 ZIP 编码(通过IP推断)、出生日期(你在某些平台上已经泄露过)和性别(你在所有地方都填写过),这三个信息组合在一起就足以唯一识别超过60%的美国人。

你总是可以添加更多变量来进一步缩小潜在候选人的范围。

信息熵

你有没有玩过 Akinator?你心里想一个角色,一个精灵通过问你大约二十个问题,竟然能猜中。这其实就是指纹识别的精髓,只不过你的浏览器会替你回答这些问题。一旦你理解了信息熵,Akinator 的“魔法”就变成了一个简单的把戏。

Let's simplify with that game where you have to guess the character on a board through questions like "Is my character a man?" If I say "yes", and half of the characters on your board are men, you're now considering only half of the total candidates. Now we can say that my answer gave you log₂(100 / 50) = log₂(2) = 1 bit of information, because it cut the pool of candidates in half.

The bits you get from one answer are called its surprisal: the rarer the answer, the more it tells you.

  • a trait shared by 1 in 2 people is worth 1 bit (is a man),
  • 1 in 8 is worth 3 bits (has a mustache),
  • and 1 in 128 is worth 7 bits (has one eye).

Surprisal quantifies the value of the answer, and entropy quantifies the value of the question. If 1 person in 128 is one-eyed, then asking about it will yield 'no' 127 times in 128.

Answer | Probability | Surprisal | Entropy contribution --- | --- | --- | --- Yes | 1/128 | log₂(128 / 1) = 7 bits | 1/128 × 7 = ~0.055 No | 127/128 | log₂(128 / 127) = ~0.0113 bits | 127/128 × 0.0113 = ~0.011

Summing up the contribution of each possible answer, the question itself is worth ~0.066 bits of entropy - that's the average amount of bits you gain from an answer.

When we combine traits that are independent we simply add up their bits or multiply the ratios, so a man with a mustache and one eye would mean 11 bits, or 1 in 2048. Alas, as Thomas Bayes would have you know, nothing is ever so simple in practice. A mustache is already a strong indicator of a man, and a man is probably more likely to have one eye. The traits are not independent so the bits don't really add up.

Some interesting applications of this type of reasoning:

  • In medical diagnostics: A positive result from a 99% accurate test for a disease known to affect 0.01% of the population is about 100 times more likely to be wrong than you are to have the disease. You need more evidence!
  • In cryptography: A password made out of four random words is as strong as eight random keyboard characters (but much easier to remember!)
  • In forensic science: singling out one person in a city of a million takes about 20 bits. A witness description that matches 1 person in 1,000 provides only 10 bits, which still leaves a thousand possible suspects.

So what can I do about it?

Test your browser:

  • coveryourtracks.eff.org shows you how unique your fingerprint is, with entropy for each measured data point.

If you're using Chrome you're basically walking around with an ID on your forehead.

Safari and Firefox offer some level of protection, but you're still identifiable by advanced trackers.

Brave, Tor and Mullvad Browser are the only major browsers at the moment that implement advanced protections against fingerprinting.

If you don't feel like switching browsers, I get it. I am a big Arc fan myself and unfortunately it's discontinued and will never have any privacy features. There are extensions like JShelter - they disrupt fingerprinting scripts by intercepting browser API calls. But they also break some websites. Same problem applies to Firefox's Resist Fingerprinting feature.

The ironic truth is, privacy extensions make you more unique, since fewer people have them. So a smart tracker could detect that, ignore the signals disrupted by the extension and focus on the ones that are not.

没有扩展程序能比浏览器内置的引擎级防护更有效。所以如果你不想被追踪,就必须做出承诺。

本页使用的方法

我仅仅是通过一些设备测量值生成一个哈希值。这些值中的任何一个发生变化,哈希值就会不同。专业级的应用要复杂得多,即使单个变量发生变化也能保持识别连续性。

  • OfflineAudioContext 通过压缩器渲染一个简短的音调而无需实际播放;结果中存在微小的浮点差异,这取决于浏览器的音频引擎和你的CPU。
javascript
const off = new OfflineAudioContext(1, 5000, 44100);
// ...将1kHz三角波输入动态压缩器...
const data = (await Promise.race([off.startRendering(), timeout])).getChannelData(0);
let sum = 0;
for (let i = 4500; i < 5000; i++) sum += Math.abs(data[i]);
return sum.toFixed(3);
  • WebGL 读取GPU厂商和型号(不带版本号)、GPU及其驱动支持的功能,以及一个小型渲染三角形的像素数据。
javascript
const gl = document.createElement('canvas').getContext('webgl');
const dbg = gl.getExtension('WEBGL_debug_renderer_info');
return gpuName(gl.getParameter(dbg ? dbg.UNMASKED_RENDERER_WEBGL : gl.RENDERER) || '');
// "ANGLE (Apple, ANGLE Metal Renderer: Apple M4, Unspecified Version)" -> "apple m4"
// ...return fnv1a(new TextEncoder().encode([...(gl.getSupportedExtensions() || []).sort(), ...limits, ...precision].join('|')));
// ...gl.drawArrays(gl.TRIANGLES, 0, 3); gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, px);
  • canvas 用几种字体、表情符号和渐变绘制文本,然后读取像素数据;抗锯齿和字体渲染取决于你的操作系统、GPU和字体。
javascript
ctx.font = '15px "Times New Roman", serif';
ctx.fillText('Sphinx of black quartz 🦊', 4, 22);
// ...const data = ctx.getImageData(0, 0, 240, 60).data;
  • Intl 你的时区以及日期和数字设置;VPN会改变你的IP位置,但不会改变时区。
javascript
const date = Intl.DateTimeFormat().resolvedOptions();
// ...return [date.timeZone, date.locale, date.calendar, date.numberingSystem, hourCycle, (1234567.891).toLocaleString()].join('/');
  • navigator 你的CPU核心数量、内存大小(仅限Chrome)和浏览器语言。
javascript
return [navigator.hardwareConcurrency, navigator.deviceMemory, navigator.language].join('/');
  • crypto.subtle 用SHA-256哈希所有值,哈希值会根据你的昵称选择一个特征和动物。
javascript
const digest = await crypto.subtle.digest('SHA-256', bytes);
// ...nickname: stranger || `${pick(TRAITS, hex, 0)} ${pick(ANIMALS, hex, 8)}`