[譯]如何識別 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')
}
複製代碼

檢測出用戶使用隱身模式以後能夠作些什麼呢?歡迎評論...

相關文章
相關標籤/搜索