WebRTC 编解码器指纹识别: 当媒体能力暴露你的平台信息
通过 getCapabilities() 和 SDP offer 进行的 WebRTC 编解码器枚举会暴露因操作系统而异的硬件媒体能力。了解编解码器列表如何成为平台指纹,以及如何加以控制。
简介
WebRTC 支持浏览器中的实时视频和音频通信。在任何媒体在对等端之间流动之前,浏览器会枚举其支持的编解码器,并通过能力 API 和 SDP(会话描述协议)offer 来暴露它们。这种协商对于功能性视频通话至关重要,但它也创建了一个详细的系统媒体能力清单,任何网站都可以在不需要特殊权限的情况下查询。
WebRTC 编解码器能力因平台而异,可以用作追踪信号。不同的操作系统提供不同级别的硬件加速支持,这直接决定了哪些编解码器出现在浏览器的能力列表中。网站可以查询这些列表并将其与已知的平台配置文件进行比较,从而推断你的真实操作系统,即使你的 user agent 字符串声称的是其他系统。
BotBrowser 通过完全从指纹配置文件构建 WebRTC 编解码器能力列表来解决这个问题,确保 JavaScript 看到的内容与配置文件的目标平台匹配,而不是主机系统的实际硬件。
BotBrowser 的解决方案
BotBrowser 在浏览器引擎层面解决 WebRTC 编解码器指纹识别,即编解码器能力实际确定的地方。BotBrowser 不是修补 JavaScript API 或后处理 SDP 字符串,而是从指纹配置文件数据构建编解码器能力列表。这确保了每个暴露编解码器信息的 API 都返回一致的、与配置文件准确匹配的结果。
配置文件驱动的编解码器构建
当加载 BotBrowser 配置文件时,WebRTC 编解码器能力是从配置文件记录的编解码器数据构建的,而不是从主机系统的实际硬件能力构建的。配置文件包含从匹配目标平台的真实设备捕获的完整编解码器配置:
- 完整的支持视频和音频编解码器列表
- 编解码器参数,包括 profiles、levels 和格式特定选项
- 能力列表中编解码器的正确排序
- 用于 SDP 生成的 payload type 分配
这意味着针对某个平台的配置文件,在完全不同的主机操作系统上加载时,仍会报告配置文件目标的正确 WebRTC 编解码器。主机系统的实际能力与 JavaScript 看到的内容无关。
SDP 一致性
BotBrowser 确保 createOffer() 生成的 SDP 与 getCapabilities() 报告的编解码器能力一致。两者都源自相同的配置文件数据,因此能力 API 报告的内容与 SDP 中出现的内容之间没有差距。
SDP 中的 m=video 和 m=audio 行包含与配置文件编解码器集对应的确切 payload type。a=rtpmap 和 a=fmtp 属性与能力对象中的参数匹配。任何查询两个 API 并比较它们的脚本都会发现完美的一致性。
功能兼容性
控制 WebRTC 编解码器的挑战之一是保持实际媒体功能。如果配置文件指定了主机系统实际无法解码的编解码器,浏览器需要优雅地处理这种情况。
BotBrowser 通过双层设计解决这个问题: JavaScript 看到配置文件的编解码器列表,而内部浏览器只注册主机系统实际可以处理的编解码器。这种分离意味着:
- 指纹脚本看到与配置文件准确匹配的编解码器列表。
- 实际的 WebRTC 通话使用双方和本地系统都能处理的编解码器进行协商。
- 当配置文件列出主机无法解码的编解码器时,不会崩溃或出错。
这是一个关键区别。简单地将编解码器条目注入能力列表会导致浏览器尝试实际使用这些编解码器时出现失败。BotBrowser 的引擎级集成正确处理了指纹呈现和功能性媒体处理之间的边界。
跨 API 对齐
BotBrowser 不仅确保 WebRTC API 内部的一致性,还确保跨完整媒体能力接口集的一致性:
RTCRtpSender.getCapabilities()和RTCRtpReceiver.getCapabilities()返回与配置文件一致的编解码器。createOffer()的 SDP offer 包含匹配的 payload type。canPlayType()和MediaCapabilities.decodingInfo()等通用媒体 API 返回与 WebRTC 编解码器配置文件一致的结果。- 整体媒体指纹讲述一个关于平台的单一、连贯的故事。
这种跨 API 对齐是 BotBrowser 保护有效的原因。所有编解码器报告路径都由单一、一致的数据源管理: 已加载的配置文件。
配置和使用
基本 CLI 用法
加载配置文件时,WebRTC 编解码器保护是自动的。不需要额外的标志:
chrome --bot-profile="/path/to/profile.enc" \
--user-data-dir="$(mktemp -d)"
配置文件的 WebRTC 编解码器配置在启动时应用。所有后续的 WebRTC 能力查询和 SDP 生成都将反映配置文件的编解码器集。
Playwright 集成
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
],
headless: true,
});
const context = await browser.newContext({ viewport: null });
const page = await context.newPage();
await page.goto('about:blank');
// Verify WebRTC codec capabilities from the loaded profile
const codecInfo = await page.evaluate(() => {
const videoCaps = RTCRtpSender.getCapabilities('video');
const audioCaps = RTCRtpSender.getCapabilities('audio');
return {
videoCodecCount: videoCaps?.codecs.length || 0,
audioCodecCount: audioCaps?.codecs.length || 0,
};
});
console.log('Video codecs:', codecInfo.videoCodecCount);
console.log('Audio codecs:', codecInfo.audioCodecCount);
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('about:blank');
// Verify WebRTC codec capabilities from the loaded profile
const codecs = await page.evaluate(() => {
const videoCaps = RTCRtpSender.getCapabilities('video');
const audioCaps = RTCRtpSender.getCapabilities('audio');
return {
videoCount: videoCaps?.codecs.length || 0,
audioCount: audioCaps?.codecs.length || 0,
};
});
console.log(`Video codecs: ${codecs.videoCount}`);
console.log(`Audio codecs: ${codecs.audioCount}`);
await browser.close();
})();
结合代理和平台设置
为了实现完整的平台一致性,将编解码器保护与代理和平台配置结合使用:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy.example.com:1080" \
--bot-config-timezone="America/New_York" \
--bot-config-locale="en-US" \
--user-data-dir="$(mktemp -d)"
这确保不仅编解码器能力与配置文件的平台一致,网络身份、时区、区域设置和所有其他信号也都对齐。
验证
配置 BotBrowser 加载配置文件后,验证 WebRTC 编解码器保护是否正常工作:
-
编解码器计数检查: 调用
RTCRtpSender.getCapabilities('video')并确认编解码器数量与配置文件目标平台的预期匹配。 -
稳定性检查: 重新加载页面并重复。编解码器的数量和类型在页面加载之间应该相同。使用相同的配置文件重启浏览器并再次验证。
-
指纹测试站点: 访问浏览器指纹测试服务并检查 WebRTC 部分。报告的编解码器不应标记任何异常。
最佳实践
-
始终使用完整的配置文件。 WebRTC 编解码器能力必须与配置文件的操作系统、浏览器版本和 GPU 配置对齐。BotBrowser 配置文件从真实设备捕获,确保所有这些维度内部一致。不要混合和匹配配置文件组件。
-
将编解码器期望与你的用例匹配。 如果你正在处理积极使用 WebRTC 进行视频通话或流媒体的网站,请确保你的配置文件编解码器集支持这些站点期望的格式。排除常用编解码器的配置文件可能会导致实际 WebRTC 会话中的协商失败。
-
结合 WebRTC IP 保护。 编解码器指纹识别和 IP 泄漏是不同的 WebRTC 隐私问题,但两者都需要解决。使用 BotBrowser 的代理集成
--proxy-server和--bot-webrtc-ice确保你的 WebRTC IP 地址也受到控制。详见 WebRTC 泄漏防护 指南。 -
不要手动修改编解码器设置。 让配置文件完全处理编解码器配置。通过 chrome 标志或配置覆盖手动添加或删除编解码器可能会产生破坏配置文件一致性的不一致。
-
保持配置文件更新。 编解码器支持随浏览器版本变化。新的编解码器被添加,现有编解码器参数可能会改变。使用与声称的浏览器版本匹配的配置文件确保你的编解码器能力与该版本的真实浏览器报告的内容一致。
-
验证跨平台一致性。 如果你在不同的主机操作系统上使用相同的配置文件(例如,在 macOS 主机和 Linux 主机上运行 Windows 配置文件),请验证两个主机上的 WebRTC 编解码器能力是否相同。BotBrowser 的配置文件驱动方法应该无论主机如何都产生相同的输出,但验证可以给你信心。
-
监控与编解码器相关的 WebRTC 错误。 如果你遇到 WebRTC 连接问题,请检查浏览器控制台中的编解码器协商错误。BotBrowser 优雅地处理配置文件编解码器和本地可用编解码器之间的差距,但某些具有不寻常对等配置的边缘情况可能需要注意。
常见问题
什么是 WebRTC 编解码器指纹识别?
WebRTC 编解码器指纹识别是一种技术,网站查询你的浏览器的 WebRTC 媒体能力来了解你的系统支持哪些视频和音频编解码器。由于编解码器支持因操作系统和硬件而异,此信息可用作追踪信号来推断你的平台详情。
这与通用媒体编解码器指纹识别有什么不同?
通用媒体编解码器指纹识别使用 canPlayType() 和 MediaCapabilities 等 API。WebRTC 编解码器指纹识别使用 WebRTC 特定的 API: RTCRtpSender.getCapabilities()、RTCRtpReceiver.getCapabilities() 和来自 createOffer() 的 SDP offer。WebRTC 编解码器集与通用媒体编解码器集不完全相同,因为 WebRTC 有自己的支持编解码器列表,反映了实时通信需求。BotBrowser 的配置文件驱动方法一致地覆盖了两个表面。有关通用媒体编解码器保护,请参阅 MIME 类型和编解码器指纹识别 文章。
网站可以在不进行通话的情况下查询 WebRTC 编解码器吗?
是的。不需要实际的 WebRTC 连接。RTCRtpSender.getCapabilities('video') 是一个静态方法,可以立即返回编解码器信息。同样,createOffer() 生成 SDP 文档而不连接到任何远程对等端。两个操作都是快速、静默的,不需要用户交互或权限。
BotBrowser 是否禁用了任何编解码器?
不。BotBrowser 不会删除或禁用编解码器功能。相反,它控制向 JavaScript 报告的编解码器信息。JavaScript 可见的编解码器列表与加载的配置文件匹配。在内部,浏览器仍然使用主机系统上可用的编解码器进行实际媒体处理。这意味着你的指纹受到控制而不会牺牲 WebRTC 功能。
如果配置文件列出了我的系统不支持的编解码器会怎样?
BotBrowser 优雅地处理这种情况。JavaScript 可见的 API 报告配置文件的编解码器列表,保持正确的指纹。当实际的 WebRTC 媒体协商发生时,浏览器内部只使用主机系统可以处理的编解码器。如果配置文件编解码器在本地不可用,它将从内部处理中排除而不影响指纹呈现。这防止了崩溃并确保通话仍然正常工作。
这是否也保护音频编解码器?
是的。BotBrowser 的配置文件驱动编解码器构建适用于视频和音频能力。来自 getCapabilities('audio') 的音频编解码器列表和 SDP offer 中的音频 payload type 也源自配置文件数据。
BotBrowser 如何处理编解码器排序?
能力列表和 SDP offer 中的编解码器排序可以携带平台特定的信息。BotBrowser 保留配置文件中的确切编解码器排序,这反映了目标平台上的自然排序。这个细节很重要,因为编解码器出现的顺序本身就是一个应该与配置文件目标匹配的信号。
这在无头模式下工作吗?
是的。WebRTC 编解码器能力在无头模式下可用,BotBrowser 的配置文件驱动编解码器构建在浏览器以无头或可见窗口运行时工作方式完全相同。
我可以在不进行真实 WebRTC 通话的情况下验证保护吗?
是的。你可以通过在页面的 JavaScript 控制台或通过 Playwright/Puppeteer 自动化调用 RTCRtpSender.getCapabilities('video') 和 createOffer() 来验证。不需要对等连接或远程服务器。配置和使用部分中的代码示例演示了这一点。
总结
通过 getCapabilities() 和 SDP offer 的 WebRTC 编解码器枚举暴露了因操作系统而异的媒体能力,使编解码器列表成为潜在的追踪信号。BotBrowser 在引擎层面解决这个问题,完全从加载的指纹配置文件构建 WebRTC 编解码器能力。每个暴露编解码器信息的 API,从 getCapabilities() 到 createOffer() SDP 生成,都返回与配置文件一致的结果。JavaScript 可见编解码器列表和内部注册解码器之间的双层分离确保你的指纹与目标平台匹配,同时实际的 WebRTC 功能继续正常工作。
结合 WebRTC IP 泄漏防护、MIME 类型和编解码器保护、跨平台浏览器配置文件 和全面的指纹验证,BotBrowser 提供了对每个可能暴露你平台身份的 WebRTC 信号的全面控制。