[译]如何识别 Chrome 浏览器的匿名窗口

原文连接:Bypassing anti-incognito detection in Google Chromehtml

浏览器的隐身窗口能够帮助用户避免 cookie 被窃取、防止被跟踪记录浏览行为。这篇文章中的一些内容可能与其余系列的浏览器类似或不一样,但我只关注基于 Chromium 的浏览器,更具体地说是谷歌的 Chrome 浏览器。git

在 Chrome 74 版本以前的浏览器中检测隐身窗口

在 Chrome 74 以前,有一个漏洞,不少网站利用这个漏洞来检测用户是否在使用 Chrome 的隐身模式访问网站。网站只需尝试使用 FileSystem API,该 API 用于存储临时或持久文件。该 API 在隐身模式下被禁用,但在非隐身模式下存在,从而产生一个差别,能够用来检测用户是否正在使用隐身模式浏览网站。web

在谷歌上随便搜索一下无痕窗口,就会获得不少结果,其中一个是 Stackoverflow 问题,被采纳的回答是:chrome

var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
    console.log("check failed?");
} else {
    fs(window.TEMPORARY,
        100,
        console.log.bind(console, "not in incognito mode"),
        console.log.bind(console, "incognito mode"));
}
复制代码

谷歌在 Chrome 74 中推出了一个新选项(经过#enable- filesystemin -incognito标志访问),阻止了这种检测。他们的解决方案是在隐身模式下使用 RAM 建立一个虚拟文件系统。该保护能够屏蔽上述检测方法,并在随后的稳定版本中默认启用。浏览器

如何检测 Chrome 74 版本及以后版本的隐身窗口?

结果代表,上面那种保护是不够的,仍然有可能检测到隐身模式,从而使目前的保护无效。最近,我在摆弄 Quota Management API 时另辟蹊径,使得即便启用了这种保护,也能够检测隐身模式。这个 API 管理分配给浏览器上的应用程序和网站的临时和持久存储的配额。使用如下摘自 Jeff Posnick 文章的代码片断,能够查询临时存储的配额:安全

if ('storage' in navigator && 'estimate' in navigator.storage) {
  navigator.storage.estimate().then(({usage, quota}) => {
    console.log(`Using ${usage} out of ${quota} bytes.`);
  });
}
复制代码

网站/应用程序有两种可用的存储方式,临时存储和持久存储,临时存储能够在不请求任何配额的状况下使用,而且由浏览器上运行的全部网站共享。cookie

关于临时存储及其配额,我经过阅读 Chromium 源代码、文章和 bug 报告收集了一些有趣的观点:(Ref1Ref2Ref3)网站

  • 对于全部应用程序/网站,临时存储的默认配额是可用磁盘的 50%,该空间做为全部应用程序/网站的共享池ui

  • 应用程序/网站能够经过调用 quota API 的 queryUsageAndQuota() 方法查询它们的配额,而不须要任何权限google

  • 隐身窗口的配额是设备内存的一小部分(10%),上限为 120MB

  • 非隐身窗口的配额只是设备存储的一小部分

下表列出了不一样磁盘大小设备的最小可用临时存储配额,该配额是根据浏览器试图在设备中始终保持空闲时来计算的。

如上图所示,隐身模式和非隐身模式的临时存储配额的关键不一样之处在于,在隐身模式下,临时存储配额固定为 120MB,而非隐身窗口则不是这样。从上表能够看出,在非隐身模式下,设备存储小于2.4GB 时临时存储配额才会小于 120MB。可是,就全部实际用途而言,能够安全地假设当前使用的大多数设备都有超过 2.4GB 的存储空间,即在非隐身模式下,临时存储配额必定大于 120MB。

利用这些信息,我想出了一个检测隐身模式的简单规则。若是临时存储配额 <= 120MB,那么能够确定这是一个隐身窗口。

if ('storage' in navigator && 'estimate' in navigator.storage) {
	const {usage, quota} = await navigator.storage.estimate();
    console.log(`Using ${usage} out of ${quota} bytes.`);

	if(quota < 120000000){
        console.log('Incognito')
    } else {
        console.log('Not Incognito')
    }	
} else {
	console.log('Can not detect')
}
复制代码

检测出用户使用隐身模式以后能够作些什么呢?欢迎评论...

相关文章
相关标签/搜索