身份

为什么隐身模式无法防御指纹追踪

隐身模式会清除 Cookie,但不会改变你的浏览器指纹。了解为什么隐私浏览不足以实现真正的隐私保护。

文档中心

想直接看维护中的产品文档?

这篇文章对应的主题已经有文档中心页面。需要规范流程、当前参数和长期参考时,优先看 docs。

简介

大多数用户认为隐身模式(或"隐私浏览")能让他们在网上隐身。实际上,隐身模式只是阻止浏览器保存本地数据:历史记录、Cookie 和表单条目不会被存储。而你的浏览器指纹,包括 Canvas 渲染、WebGL 特征、音频处理、字体可用性、屏幕尺寸以及数十种其他信号,完全保持不变。更糟的是,隐身模式会以某些方式改变浏览器行为,使得隐身会话本身可被识别。

BotBrowser 采用了一种根本不同的方法。BotBrowser 配置文件不是在具有可检测限制的隐私浏览模式下运行,而是呈现一个完整的、正常的浏览器环境,并带有受控的指纹信号。本文解释隐身模式实际上做了什么(以及没做什么)、为什么它可能让你更加显眼,以及 BotBrowser 如何提供真正的身份控制。

隐私影响

用户对隐身模式的预期与其实际提供的功能之间存在巨大差距:

隐身模式做了什么:

  • 不保存浏览历史
  • 会话关闭后不持久化 Cookie
  • 不保存表单数据
  • 将会话与常规浏览数据隔离

隐身模式没有做什么:

  • 不改变你的浏览器指纹
  • 不改变你的 IP 地址
  • 不防御基于指纹的追踪
  • 不阻止网站在会话期间识别你
  • 不改变你的 User-Agent、屏幕尺寸或硬件特征

隐身模式带来的虚假安全感本身就是一种隐私风险。相信自己受到保护的用户可能会减少采取的预防措施,而他们的指纹对追踪系统来说完全可见。

此外,隐身模式会产生一些特征,使其与正常浏览有所不同。存储配额值、API 可用性和某些浏览器行为在隐身会话中有所不同。这些差异意味着处于隐身模式本身就是一条可识别的信息。

技术背景

隐身模式如何改变浏览器行为

当浏览器进入隐身模式时,几个内部行为会发生变化:

存储配额: 在隐身模式下,浏览器通常报告减少的存储配额。navigator.storage.estimate() 返回与正常会话不同的值。具体的配额值因浏览器版本而异,但减少是一个一致的信号。

FileSystem API: 历史上,window.requestFileSystem API(或 window.webkitRequestFileSystem)在隐身模式下的行为不同。虽然现代 Chrome 已经解决了一些差异,但细微的行为变化仍然存在。

Service Workers: 隐身模式具有不同的 Service Worker 生命周期。在隐身模式下注册的 Service Worker 不会被持久化。注册行为和存储持久性与正常模式不同。

IndexedDB 和 localStorage: 虽然这些 API 在隐身模式下可用,但其存储限制和错误行为可能不同。某些浏览器在隐私模式下会限制 IndexedDB 操作。

性能特征: 内存管理和缓存行为在隐身模式下有所不同。这些差异可能影响计时测量和性能指标。

指纹保持不变

尽管上述行为发生了所有变化,核心指纹信号在隐身模式下保持不变:

  • Canvas 渲染: 相同的硬件产生相同的 Canvas 哈希
  • WebGL: 相同的 GPU 报告相同的供应商、渲染器和渲染输出
  • 音频处理: 相同的音频硬件产生相同的 AudioContext 指纹
  • 屏幕尺寸: 相同的显示器报告相同的分辨率
  • Navigator 属性: CPU 核心数、内存、平台和语言保持不变
  • 字体: 安装的字体相同
  • Client Hints: 发送相同的 User-Agent 和 Client Hints

这意味着,在正常模式下访问某个网站然后在隐身模式下再次访问的用户会产生相同的指纹。追踪系统可以通过指纹匹配来关联这两次访问,无论隐身会话如何。

"隐身信号"

上面列出的行为差异创造了所谓的"隐身信号"。一个观察到存储配额减少、FileSystem API 行为不同或其他隐身特定特征的追踪系统知道用户正在使用隐私浏览模式。

这个信号有两个含义:

  1. 人群分割: 使用隐身模式的用户是所有浏览器会话中的少数。被识别为隐身用户会将你放入一个更小的人群中,这使得你的指纹更加独特。

  2. 意图信号: 启用隐身模式的用户正在积极尝试保护自己的隐私。这种意图本身就是一个追踪系统可以纳入其模型的行为信号。

常见方法及其局限性

仅使用隐身模式

如上所述,隐身模式不改变指纹并创建可检测的特征。它可以防止本地数据持久化(对共享计算机有用),但不提供任何针对基于指纹追踪的保护。

隐身模式加扩展

在隐身模式中添加隐私扩展(如 Canvas 拦截器或指纹随机化器)会引入额外的可检测特征。基于扩展的指纹修改可以通过原型链检查、计时异常以及缺失或更改的 API 属性来检测。

隐身模式加 VPN

VPN 会改变你的 IP 地址,这解决了追踪的一个方面。但指纹,包括隐身特定的特征,保持不变。这种组合可以防止基于 IP 的追踪,但不能防止基于指纹的追踪。

Tor Browser

Tor Browser 采用了更激进的方法,将许多指纹信号标准化以匹配一个共同基线。然而,Tor Browser 的指纹本身就很独特。特定的设置组合(letterboxing、禁用 WebGL、NoScript 等)将用户识别为 Tor Browser 用户,这是一个很小的人群。

基于配置文件的方法(BotBrowser)

BotBrowser 不使用隐身模式。每个会话作为标准浏览器实例运行,具有完整的 API 访问权限、正常的存储配额和完整的 Service Worker 支持。指纹通过配置文件控制,而不是通过模式限制。

BotBrowser 的方法

正常浏览器模式加受控身份

BotBrowser 会话是常规(非隐身)浏览器会话。这是一个有意的设计选择:

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

该会话具有:

  • 正常存储配额: navigator.storage.estimate() 返回与常规浏览会话一致的值
  • 完整 API 可用性: 所有浏览器 API 正常工作,包括 FileSystem、Service Workers 和 IndexedDB
  • 标准行为: 没有隐身特定的特征存在
  • 受控指纹: Canvas、WebGL、音频、navigator、屏幕和字体信号全部由配置文件定义

配置文件定义的身份

BotBrowser 配置文件代表从真实设备捕获的完整、真实的浏览器环境。当你加载一个配置文件时,浏览器呈现与该设备一致的信号:

  • Canvas 渲染产生配置文件预期的哈希
  • WebGL 报告配置文件的 GPU 供应商和渲染器
  • 音频处理匹配配置文件的音频特征
  • 屏幕尺寸、色深和像素比匹配配置文件
  • Navigator 属性(CPU 核心数、内存、平台)与配置文件的设备一致

这与隐身模式根本不同,隐身模式通过未修改的指纹暴露你的真实硬件。

无需隐身的会话隔离

BotBrowser 通过 --user-data-dir 实现会话隔离,而不是通过隐身模式:

# 会话 1 - 隔离的数据目录
chrome --bot-profile="/profiles/profile-a.enc" \
       --user-data-dir="/data/session-1"

# 会话 2 - 独立的数据目录
chrome --bot-profile="/profiles/profile-b.enc" \
       --user-data-dir="/data/session-2"

每个会话都有自己的 Cookie、localStorage、IndexedDB 和缓存,没有隐身模式引入的行为特征。

对于不应持久化数据的临时会话,使用临时目录:

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

临时目录在系统清理临时文件时被删除,实现与隐身模式相同的数据不持久性,但没有可检测的特征。

配置与使用

基本非隐身设置

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)" \
       --proxy-server=socks5://user:pass@proxy:1080

Playwright 集成

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
      '--proxy-server=socks5://user:pass@proxy:1080',
    ],
    headless: true,
  });

  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto('https://example.com');

  // 验证正常(非隐身)行为
  const quota = await page.evaluate(async () => {
    const est = await navigator.storage.estimate();
    return est.quota;
  });
  console.log('Storage quota:', quota);
  // 返回正常配额值,而非减少的隐身值

  await browser.close();
})();

Puppeteer 集成

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
    defaultViewport: null,
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');

  // 所有 API 正常工作
  const swSupport = await page.evaluate(() => 'serviceWorker' in navigator);
  console.log('Service Worker support:', swSupport); // true

  const storageEstimate = await page.evaluate(async () => {
    const est = await navigator.storage.estimate();
    return { quota: est.quota, usage: est.usage };
  });
  console.log('Storage:', storageEstimate);

  await browser.close();
})();

持久会话

对于需要跨重启持久化数据的会话:

# 首次运行 - 创建会话数据
chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="/data/persistent-session"

# 第二次运行 - 保留 Cookie、localStorage 等
chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="/data/persistent-session"

BotBrowser 的 --bot-cookies 标志提供无需隐身模式的 Cookie 管理:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-cookies='[{"name":"session","value":"abc123","domain":".example.com"}]' \
       --user-data-dir="$(mktemp -d)"

这在一个干净的浏览器实例中恢复会话状态,没有隐身模式的特征。

验证

启动 BotBrowser 后,验证会话是否表现为正常(非隐身)会话:

const page = await context.newPage();

// 1. 检查存储配额(应为正常值,非减少值)
const quota = await page.evaluate(async () => {
  const est = await navigator.storage.estimate();
  return est.quota;
});
console.log('Storage quota:', quota);

// 2. 检查 Service Worker 可用性
const swAvailable = await page.evaluate(() => 'serviceWorker' in navigator);
console.log('Service Worker available:', swAvailable);

// 3. 检查 IndexedDB
const idbAvailable = await page.evaluate(() => {
  return new Promise((resolve) => {
    const req = indexedDB.open('test', 1);
    req.onsuccess = () => { req.result.close(); resolve(true); };
    req.onerror = () => resolve(false);
  });
});
console.log('IndexedDB available:', idbAvailable);

// 4. 验证指纹受控(不是你的真实硬件)
const canvas = await page.evaluate(() => {
  const c = document.createElement('canvas');
  const ctx = c.getContext('2d');
  ctx.fillText('test', 10, 10);
  return c.toDataURL().slice(-20);
});
console.log('Canvas hash suffix:', canvas);

确认:

  1. 存储配额是正常值(不是减少的隐身值)
  2. 所有 API 都可用且功能正常
  3. Canvas 和其他指纹信号来自配置文件,而非你的真实硬件
  4. 没有隐身特定的特征存在

最佳实践

  1. 永远不要将隐身模式与 BotBrowser 一起使用。 BotBrowser 配置文件专为正常浏览器会话设计。隐身模式会添加不必要的特征。

  2. 使用 --user-data-dir 进行会话隔离。 独立的用户数据目录提供干净的隔离,没有行为特征。

  3. 使用临时目录进行非持久会话。 mktemp -d 创建一个由操作系统清理的唯一临时目录。

  4. 始终加载配置文件。 不使用 --bot-profile 运行 BotBrowser 意味着没有指纹保护。配置文件是基础。

  5. 结合代理实现完整身份。 配置文件控制指纹。代理控制网络身份。两者都需要才能构成一致的身份。

  6. 使用 --bot-cookies 进行会话恢复。 不要依赖数据目录中的持久 Cookie,而是使用 --bot-cookies 标志显式管理 Cookie 以实现可重复的会话。

常见问题

我可以在隐身模式下使用 BotBrowser 吗? 可以,但不应该。隐身模式会添加可检测的特征,而不提供额外的指纹保护。BotBrowser 基于配置文件的方法在正常模式下提供更好的隐私保护。

BotBrowser 能防止本地数据持久化吗? 通过使用临时的 --user-data-dir,会话数据不会被持久化。这实现了与隐身模式相同的数据不持久性目标,但没有相关特征。

Firefox 或 Safari 中的隐私浏览呢? 相同的原则适用。所有浏览器中的隐私浏览模式都会创建可检测的特征,同时保持核心指纹不变。基于配置文件的指纹控制是更有效的方法。

网站能否检测到我不在隐身模式下? 在正常的 BotBrowser 会话中,浏览器的行为与标准 Chrome 会话完全相同。没有什么异常可以检测到。这就是不使用隐身模式的优势。

隐身模式能防止 IP 追踪吗? 不能。隐身模式不会改变你的 IP 地址。要保护 IP,请将代理与 BotBrowser 一起使用。

Firefox 的"增强追踪保护"呢? Firefox 的增强追踪保护会阻止已知的追踪器并限制某些指纹采集。然而,它无法像 BotBrowser 配置文件那样控制底层指纹信号。该保护也可以通过被阻止请求的缺失来检测。

我可以在没有隐身的情况下运行多个会话吗? 可以。为每个会话使用独立的 --user-data-dir 路径。每个目录提供完全隔离:独立的 Cookie、缓存、localStorage 和 IndexedDB,没有隐身特征。

BotBrowser 的方法适用于所有网站吗? 是的。因为 BotBrowser 会话是标准浏览器会话,它们与所有网站兼容。没有可能导致兼容性问题的 API 限制或行为差异。

总结

隐身模式提供本地数据不持久性,但无法保护你的浏览器指纹。更糟的是,它引入了可检测的特征,使你的会话更加独特。BotBrowser 采用不同的方法:正常浏览器会话加上配置文件控制的指纹信号。这提供了真正的身份控制,没有隐私浏览模式的限制和特征。

有关完整的身份配置,请参阅 Browser Brand SwitchingUser Agent Control and Client HintsTimezone, Locale, and Language Configuration。有关网络身份,请参阅 Proxy ConfigurationMulti-Account Browser Isolation

#Incognito#Private-Browsing#Detection#Identity#Privacy

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。