Rebrowser Patches:代理通畅后,哪些值会变?
在同一自有页面比较 Rebrowser 补丁、原生 Playwright 与声明式浏览器 profile,区分库行为、渲染观测和代理路由,保留音频相同及配置混杂的实测边界。
BotBrowser Team
Rebrowser 代理连接正常,并不代表浏览器的 canvas 输出、字体或音频处理已有明确配置。先确认应用使用的是开源 Rebrowser 库补丁、托管浏览器服务,还是同时使用两者。这些是不同配置。BotBrowser 为浏览器暴露的图形、字体和音频提供声明式 profile 控制,但不能保证目标网站的决定,也不能让代理变化自动定义完整的浏览器环境。
TL;DR
- 固定版本的 Rebrowser 补丁修改自动化库代码,包括执行上下文处理与启动参数,不会替换 Chrome 可执行文件。
- CDP 可以执行脚本,也可以在文档运行前安装脚本。某个 API 不在特定补丁的修改范围内,不等于 CDP 无法触及它。
- 在 Ubuntu 的一个自有 fixture 上,原生 Playwright 与补丁库各自三次独立启动,返回的四项渲染观测相同。声明式 profile 配置改变了三项观测,音频结果仍然相同。
- profile 配置使用了不同的浏览器补丁版本,并在 Ubuntu 上声明 Windows 目标。差异是这套配置的观测,不能单独归因于某一实现层。
目录
- 区分 Rebrowser 包、代理与云端浏览器
- 先读实际补丁,再判断边界
- 在同一自有页面比较三种配置
- 分别解释 canvas、WebGL、字体与音频
- 用自有页面复现观测
- 根据失败操作选择下一项检查
- 实践结论
区分 Rebrowser 包、代理与云端浏览器
rebrowser proxy 这个说法可能混合三个独立问题:运行的是哪个自动化包、浏览器在哪里运行,以及请求走哪条路径。应分别明确记录。安装一个包不能证明请求使用了代理。连接远程浏览器也不能证明它的文件系统、profile 或可执行文件与本地安装相同。公网出口改变,并不能说明渲染输入也发生了变化。
| 配置 | 它确定的内容 | 仍需单独取证的内容 |
|---|---|---|
| 原生 Playwright 包 | 自动化库及其版本 | 浏览器可执行文件、启动参数与网络路径 |
| Rebrowser drop-in 包 | 应用了该项目补丁的库 | 实际加载的包、底层 Chrome 与所选补丁设置 |
| 代理连接 | 分配给该代理的流量路径 | 浏览器设置、存储状态与目标网站的解释 |
| 托管浏览器会话 | 远程运行的浏览器服务 | 服务特有配置、持久化方式与网络行为 |
| 声明式浏览器 profile | 应用于受支持浏览器环境的输入 | 成功加载、实际输出与应用兼容性 |
固定提交的官方 README 将 drop-in 包描述为应用补丁后的原始库,并另外介绍供应商的云服务。因此,本地包实验不能支持有关云产品浏览器身份、代理供应、价格或成功率的结论。下方对照没有使用 Rebrowser 云端会话。
如果请求走错路径,应先看网络证据。自有观察端确定出口地址,源站标记确定收到的是哪个请求。浏览器图形值无法说明隧道是否完成认证。保留上下文的路由诊断 讨论流量路径变化;Launcher 工作流程 讨论配置后浏览器会话的启动与管理。路径证据和 Launcher 成功,都不能替代检查应用实际加载的包。
不要把代理凭据写进对照记录。包名、版本、浏览器哈希、路径标签及自有观察端响应,通常足以区分这些问题。如果没有获准使用的观察端,就把路径标记为未验证。页面成功渲染不能确定内容来自哪条路径,请求被拒绝也不能确定目标网站考虑了哪个浏览器属性。
先读实际补丁,再判断边界
检查的源代码来自 Rebrowser patches 提交 31b51356499600f71126aae532f3d57abdc92272,包括面向 Playwright 1.64.1 的补丁。实际运行的包为 [email protected] 和 [email protected]。包版本与补丁面向的上游版本是不同标识,应同时保留,不能假定最后一段数字必须一致。
固定版本的源码补丁 修改执行上下文设置、utility world 命名及其他库行为。启动参数变化涉及 Blink 的自动化控制设置,也修改了若干默认开关。这比把该项目笼统称为一组页面属性替换更准确。有些改动影响库与 Chrome 的通信方式,有些影响 Chrome 启动时接收的选项。
这些细节也解释了为什么 canvas 结果不变,不能证明补丁失效。上下文管理与 canvas 像素修改有不同目的。即使自动化库采用不同的初始化路径,渲染器仍可能产生完全相同的字节。反过来,从某个 API 读到不同字符串,也不能证明浏览器其余环境保持一致。
协议的一般能力边界同样需要准确表述。CDP 文档提供 Runtime.evaluate 与 Page.addScriptToEvaluateOnNewDocument。协议客户端可以运行页面脚本,包括影响 JavaScript 可见行为的脚本。因此,“这些固定版本补丁没有配置这项渲染输出”是在描述具体实现。“CDP 无法影响渲染 API 的值”则是宽泛得多的断言,文档中的脚本执行能力并不支持这种说法。
执行 world 也是一个实验输入。在 isolated world 中求值的脚本,并不与文档 main world 共享所有 JavaScript 绑定。如果对照同时改变库和读取值的 world,就可能把差异归因于错误输入。这个 fixture 由文档自己的脚本完成观测,再把结果 POST 回同源服务。驱动负责导航并等待送达,不在库所选的 world 中求值观测函数来采集数值。
不能根据源码检查推断目标网站的结果。源码能确定某个具体修订修改了什么,但不能确定它在所有 Chrome 版本上的后果、另一个名称相似的已安装包的行为,或网站如何做决定。这里没有独立验证 Rebrowser 对第三方网站的说法,也不把这些说法作为实验结果。
在同一自有页面比较三种配置
受控运行使用 Ubuntu,同一显示服务上的有头浏览器、请求尺寸为 1280 × 900 的 viewport 和全新独立的浏览器数据目录。每种配置运行三次,九个任务进入同一个全局池。请求的池上限为 20,按实际九个任务封顶。进程采样观察到九条浏览器执行通道同时活跃,supervisor 验证本轮没有残留进程。原生与补丁页面实际报告 1280 × 900,声明式配置报告 1288 × 944,因此三组的实际 viewport 尺寸并未保持一致。
| 分组 | 自动化包 | 实际可执行文件版本 | Profile |
|---|---|---|---|
| 原生 | [email protected] | 原版 Chrome 157.0.8103.50 | 不加载声明式产品 profile |
| 补丁 | [email protected] | 同一个原版 Chrome 157.0.8103.50 | 不加载声明式产品 profile |
| 声明式 | [email protected] | BotBrowser 157.0.8103.38 | 在 Ubuntu 上使用 Chromium 157 Windows x64 目标 |
原生与补丁的比较保持原版可执行文件不变。第三组同时改变可执行文件与目标配置。三组共享浏览器大版本,但完整版本并不相同。第三列的差异不能唯一确定 profile、可执行文件补丁版本或某一实现层的作用。这是一份带有明确边界的配置记录,不能作为某个层面更优的受控结论。
下表只为便于阅读而使用完整 SHA-256 的前缀。完整数值、算法、重复观测与环境记录保存在可执行 fixture 的输出中。前缀只是本轮的标签,不是身份评分。
可检查观测记录、本地对照脚本和自有页面源码。将脚本保存为 .mjs 扩展名,并把页面以 render-fixture.html 为名保存在旁边。公开脚本复现页面观测,不执行受控运行验收所用的独立 profile 加载审核。
| 观测 | 原生 | 补丁 | 声明式 profile |
|---|---|---|---|
| Canvas RGBA SHA-256 前缀 | 26cd080f5b96 | 26cd080f5b96 | 0119c1c2e040 |
| WebGL renderer,简写 | ANGLE, Vulkan, SwiftShader | ANGLE, Vulkan, SwiftShader | ANGLE, NVIDIA Quadro P1000, Direct3D11 |
| 候选字体命中 | Arial; Times New Roman; Courier New; DejaVu Sans; Liberation Sans | 相同的五个候选 | Arial; Times New Roman; Courier New |
| 离线音频样本 SHA-256 前缀 | 0d6f33df90bb | 0d6f33df90bb | 0d6f33df90bb |
| 末 500 个音频样本绝对值之和 | 124.04347776696522 | 124.04347776696522 | 124.04347776696522 |
每组的三次全新启动都重复得到这些观测。尤其是,对于这个输入,声明式 profile 组的音频样本没有变化。对照必须保留这种相等结果,不能把它概括成 profile 配置会改变每一个指纹表面。
通过验收的运行由 supervisor 输出:
"comparisonPermitted": true,
"peakActive": 9,
这个许可表示实验的本地前置条件通过。最初几次尝试缺少必需的 profile 加载日志证据,因此没有被接受为三组对照结果。最终运行保留了对准确加密文件的解密成功与加载证据,也取得同一页面上下文中声明的 Windows 身份。文件名、已启动进程或已连接的 CDP 会话,都不单独视为成功加载的证明。
没有联系外部网站取得检测器结论。fixture 没有使用代理,因此不能测量 Rebrowser 代理性能,也不能比较代理供应商。结果只回答较窄的问题:在所记录的本地配置下,这四项页面观测是否变化。
分别解释 canvas、WebGL、字体与音频
Canvas 对照使用固定的 300 × 80 canvas,以及固定形状、颜色和文本。在图像编码之前,对 getImageData 返回的全部 96000 字节计算 SHA-256。如果改为比较 PNG 文件或 data URL,就引入了不同的序列化输入。重复测量时,应保留文本、请求的字体、尺寸和绘制顺序。哈希变化可以确定输出变化,但不能解释原因究竟是字体、栅格化、浏览器选项还是其他输入。
WebGL 对照在 WEBGL_debug_renderer_info 可用时记录它暴露的 renderer。报告的 renderer 是一个对外暴露的值,不能作为经过验证的物理硬件清单。Windows 目标配置在 Ubuntu 上运行,却报告 Direct3D renderer,因此不能把这段字符串当成宿主安装的 GPU。如果扩展或上下文不可用,应明确记录 unavailable,不能把空 renderer 字符串悄悄当作匹配结果。
字体刻意只做有限候选实验。候选为 Arial、Times New Roman、Courier New、DejaVu Sans、Liberation Sans 和 Noto Sans。fixture 将每个候选的固定文本宽度,与 serif、sans-serif、monospace 后备字体比较。命中只表示候选在这套方法下改变了测得的宽度,不能证明准确字体文件存在、枚举全部安装字体,或区分所有别名与替代字体。完整输出同时保留宽度和命中列表,避免粗略标签遮蔽原始观测。
离线音频使用单通道、5000 帧、44100 Hz、triangle oscillator 和固定 compressor 配置。输出记录 Float32 样本字节的摘要,以及最后 500 个样本的绝对值之和。这是离线计算,不是从麦克风、声卡或扬声器录音。样本相同,只能确定这个音频图与输入的结果相同,不能确定所有音频 API、设备或处理图都具有相同行为。
组内相同也不等于长期稳定。同一宿主上的三次全新启动,不能确定操作系统升级、字体变化、GPU 驱动变化或换用另一浏览器构建后,数值仍然相同。同样,单项观测不同也不能揭示远程系统如何组合信号。浏览器表面控制文档 说明产品可配置的范围;表格只确定所选配置实际观察到的行为。
用自有页面复现观测
使用自己控制的页面,并在各组保持采集脚本完全相同。固定两个自动化包,显式传入可执行文件路径。Playwright 文档指出,替代可执行文件路径存在兼容性风险,因此,已测试 Chrome 版本运行成功,不能扩展成任意未来版本均可工作的承诺。开始比较之前,应把启动失败记录为 setup failure。
一个小型本地复现可以提供页面并保存它 POST 的结果,无需第三方检查器做解释。使用 Node.js 时,结果接收部分可以写成:
import http from 'node:http';
import { readFile, writeFile } from 'node:fs/promises';
const page = await readFile('./render-fixture.html');
const server = http.createServer(async (request, response) => {
if (request.method === 'GET' && request.url === '/') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.end(page);
return;
}
if (request.method === 'POST' && request.url === '/results') {
const chunks = [];
let size = 0;
for await (const chunk of request) {
size += chunk.length;
if (size > 131072) {
response.writeHead(413).end();
return;
}
chunks.push(chunk);
}
const record = JSON.parse(Buffer.concat(chunks).toString('utf8'));
await writeFile('./observation.json', JSON.stringify(record, null, 2));
response.writeHead(200).end('recorded');
return;
}
response.writeHead(404).end();
});
server.listen(0, '127.0.0.1');
这个接收示例并不是完整的浏览器 supervisor:每个任务应使用独立结果文件,设置总时限,并在结果送达后关闭自己的服务器与浏览器上下文。完整对照 fixture 分开管理这些任务,并记录进程回收。固定等待一段时间不是它的完成条件。它等待自有页面的结果 POST;观测缺失或无效时,任务仍然失败。
只比较渲染时,应使用全新独立的数据目录。多个并发进程共享同一可写浏览器目录,会引入锁与状态干扰。如果真正的问题是会话连续性,应另建从受控关闭快照开始的测试合同,不能悄悄把存储状态变化混入渲染对照。同样,应固定启动模式与 viewport,不能在更换库的同时切换有头与无头模式。
保留不受支持或未变化的输出。两个原版分组中都未命中的候选字体、不可用的图形扩展,或没有变化的音频结果,可能比整齐的“全部不同”表格更有价值。这些记录解释了哪个假设环节没有成立,无需把它们转化为产品推荐。库和浏览器责任范围的更广泛区别,可参考通用补丁表面对照;这个固定版本实验提供的是具体观测。
根据失败操作选择下一项检查
安装 Rebrowser 后,如果应用仍有异常行为,应保留第一次失败的操作。下一项有效行动取决于失败发生在导入包、启动 Chrome、通过代理导航、执行应用代码,还是接收目标响应。没有确定这一层就修改浏览器设置,会让人更难判断究竟哪项改动起了作用。
| 症状 | 首先保留的证据 | 下一项受控行动 |
|---|---|---|
| 补丁看起来没有效果 | 已加载包的名称、版本与解析位置 | 确认应用导入的是补丁 core,而不是其他已安装副本 |
| 浏览器无法启动 | 可执行文件版本、启动错误与所选库 | 使用已知的受控页面检查兼容性 |
| 请求走了意外路径 | 自有观察端结果与路径配置 | 将路由问题与图形设置分开修正 |
| 渲染值保持不变 | 相同页面输入、可执行文件与观测方法 | 检查该固定版本补丁是否实际修改这项输入 |
| 应用代码在不同 world 中表现不同 | 上下文选择及对文档绑定的访问 | 修改数值前先检查执行 world 要求 |
| 目标拒绝某项操作 | 实际响应与运营方公布的政策 | 停在获准诊断的边界,不推断隐藏评分规则 |
如果工作区存在多个依赖树或别名,导入检查不能只看 package.json。应记录从正在运行的应用位置实际解析出的版本。固定版本的 Rebrowser README 记载了历史上的 drop-in/core 依赖问题,这说明需要验证实际包,并不意味着每个安装都存在该问题。重新安装一个无关顶层包,不能确定应用究竟加载了哪个 core。
对于渲染要求,先定义所需输出,再选择控制项。仅需页面成功渲染的工作负载,与必须跨会话保留声明图形设置的工作负载,有不同的验收检查。BotBrowser 的自动化一致性参考 说明这个边界上的产品行为,但配置 profile 或使用库补丁,都不能认证目标网站的身份分类。
常见问题
Rebrowser 会替换 Chrome 吗?
检查的开源 drop-in 库修改自动化库代码,使用另外提供或安装的浏览器。托管服务属于不同的产品范围。
CDP 客户端能影响 canvas 值吗?
CDP 可以执行页面脚本。能够支持的说法是某个具体实现实际修改了什么,不能说协议绝对无法影响 JavaScript 可见的结果。
数值相同是否说明补丁什么都没做?
不是。这个 fixture 测量四项渲染观测。库对上下文设置或启动参数的修改,即使没有改变这四项输出,也可能有其作用。
代理会给浏览器换一个 profile 吗?
代理配置为作用范围内的流量选择路径,本身并不定义字体、canvas 输入或离线音频图。
来源
- 所检查提交的 Rebrowser patches README
- Rebrowser 的 Playwright 1.64.1 源码补丁
- CDP Runtime.evaluate
- CDP Page.addScriptToEvaluateOnNewDocument
- Playwright 的 executablePath 兼容性说明
- BotBrowser 浏览器表面总览
- BotBrowser 自动化一致性
实践结论
从准确的包、可执行文件和失败操作开始。在这个固定实验中,Rebrowser 库补丁的四项渲染观测与原生 Playwright 相同;声明式 profile 配置改变了 canvas、renderer 和候选字体观测,但音频仍相同。这些结果回答本地配置问题,不能给产品排名、描述云服务或预测目标网站的决定。应将路由、自动化库行为和声明的浏览器设置,保留为可以分别验证的输入。
本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界